队列
队列:是一个有序列表,可以用数组或是链表来实现。 遵循先入先出的原则。即:先存入队列的数据,要先取出。后存入的要后取出。
模拟实现一个队列:
public class ArrayQueueDemo {
public static void main(String[] args) throws Exception {
ArrayQueue arrayQueue = new ArrayQueue(10);
arrayQueue.add(5);
arrayQueue.display();
arrayQueue.add(10);
arrayQueue.display();
arrayQueue.get();
arrayQueue.get();
arrayQueue.get();
}
}
//使用数组模拟队列-->编写一个ArrayQueue类
class ArrayQueue{
private int maxSize;//队列最大长度
private int front;//队列头
private int rear;//队列尾
private int[] arr;//存放数据
public ArrayQueue(int size){
maxSize=size;
arr=new int[maxSize];
//初始化时队列头尾都指向第一个元素下方位置
front=-1;
rear=-1;
}
//队列是否已经满了
public boolean isFull(){
return rear==maxSize-1;
}
//队列是否为空
public boolean isEmpty(){
return rear==front;
}
//添加数据
public void add(int e){
if(isFull()){
System.out.println("队列已经满了,不能添加~");
return;
}
rear++;//后移一位
arr[rear]=e;
}
//移除数据
public int get() throws Exception {
if(isEmpty()){
throw new RuntimeException("队列为空");
}
front++;
return arr[front];
}
//显示队列数据
public void display(){
if(isEmpty()){
System.out.println("队列为空");
}
System.out.println("-------显示数据--------");
for (int i = 0; i < arr.length; i++) {
System.out.println(i+"="+arr[i]);
}
}
//显示头元素
public int getHeader(){
if(isEmpty()){
throw new RuntimeException("队列为空");
}
return arr[front+1];
}
}
示意图:
存在问题:当元素移除后,下标上移,之前元素依然存在,无法继续添加数据。
环形队列
环形队列在逻辑上是环形的, 但在物理上是一个定长的数组。
针对上例存在问题,我们做如下调整:
1.front指向第一个元素索引,即arr[front] 就是数组第一个元素
2.rear指向最后一个元素的后一个位置
3.当队列满的条件是:(rear+1)%maxSize=front
4.队列为空条件是:rear==front
代码:
public class CirceArrayQueueDemo {
public static void main(String[] args) throws Exception {
CirceArrayQueue arrayQueue = new CirceArrayQueue(3);//设置为3 实际有效长度为2
arrayQueue.add(5);
arrayQueue.add(10);
arrayQueue.display();
arrayQueue.get();
System.out.println("取出一个元素后,对头元素:"+arrayQueue.getHeader());
arrayQueue.add(7);
arrayQueue.add(4);
arrayQueue.display();
}
}
class CirceArrayQueue{
private int maxSize;//队列最大长度
private int front;//队列头 指向第一个位置
private int rear;//队列尾 指向最后元素位置后一位
private int[] arr;//存放数据
public CirceArrayQueue(int size){
maxSize=size;
arr=new int[maxSize];
//初始化时队列头尾都指向第一个元素
front=0;
rear=0;
}
//队列是否已经满了
public boolean isFull(){
return (rear+1)%maxSize==front;
}
//队列是否为空
public boolean isEmpty(){
return rear==front;
}
//添加数据
public void add(int e){
if(isFull()){
System.out.println("队列已经满了,不能添加~");
return;
}
arr[rear]=e;
rear=(rear+1)%maxSize;
}
//取出数据
public int get() throws Exception {
if(isEmpty()){
throw new RuntimeException("队列为空");
}
int value=arr[front];
//front后移考虑取模
front=(front+1)%maxSize;
return value;
}
//显示队列数据
public void display(){
if(isEmpty()){
System.out.println("队列为空");
return;
}
System.out.println("-------显示数据--------");
//从front开始遍历,遍历多少个元素
for (int i = front; i < front+size(); i++) {
System.out.println(i%maxSize+"="+arr[i%maxSize]);
}
}
//求出当前队列有效数据
public int size(){
return (rear+maxSize-front)%maxSize;
}
//显示头元素
public int getHeader(){
if(isEmpty()){
throw new RuntimeException("队列为空");
}
return arr[front];
}
}