maxSize
是该队列的最大容量front
和rear
)。其中front
会随着数据的输入而改变,rear
会随着队列的输出而改变基本思路分析:
rear==maxSize-1
public boolean isFull() { return rear == maxSize - 1; }
rear==front
public boolean isEmpty() { return rear == front; }
addQueue()
,其实现需要有两个步骤
rear+1
;real
小于队列的最大下标maxSize-1
,则将数据存入rear
指向的数组元素中。当rear==maxSize-1
时队列满,不能存入数据public void addQueue(int n) { //判断队列是否已满,已满则不能添加数据 if (isFull()) { System.out.println("队列已满,不能添加数据"); return; } arr[++rear] = n; //先将rear后移,在将数据加入队列 }
front
后移在输出其指向的数据(front
指向的是头数据的前一个位置)public int getQueue() { //判断队列为空,若为空这抛出异常 if (isEmpty()) { throw new RuntimeException("队列为空,不能取数据"); } return arr[++front];//先将front后移使其指向要出队列的元素,然后返回其指向的元素 }
public int headQueue() { //判断队列是否为空,为空则无头数据 if (isEmpty()) { throw new RuntimeException("队列为空,没有数据"); } return a[front + 1];//注意front指向的是头数据的前一个位置,使用在读取头数据的时候的指针为front+1 }
数组模拟队列的完整实现如下:
public class ArrayQueue { private int maxSize; //队列的最大容量 private int[] arr; //用于存放数据,模拟队列 private int front; //队列头,实际上指向队列头数据的前一个数据 private int rear; //队列尾,实际上指向队列尾的数据 //初始化队列通过构造方法完成 public ArrayQueue(int maxSize) { this.maxSize = maxSize; arr = new int[maxSize]; front = -1; rear = -1; } //判断队列是否为空的方法 public boolean isEmpty() { return rear == front; } //判断队列是否已满的方法 public boolean isFull() { return rear == maxSize - 1; } //向队列里添加数据的方法 public void addQueue(int n) { //先判断队列是否已满 if (isFull()) { System.out.println("队列已满,不能加入数据"); return; } arr[++rear] = n; } //取出队列数据的方法 public int getQueue() { //先判断队列是否为空 if (isEmpty()) { throw new RuntimeException("队列已空,不能取数据"); } return arr[++front]; } //查看头数据的方法 public int headQueue() { //判断队列是否为空 if (isEmpty()) { throw new RuntimeException("队列已空,没有数据"); } return arr[front + 1]; } //辅助方法,显示队列所有数据 public void list() { //判断队列是否为空 if (isEmpty()) { System.out.println("队列为空,没有数据"); return; } for(int i = 0; i < arr.length; i++) { System.out.printf("arr[%d]=%d\n", i, arr[i]); } } }
顺序队列存在一个问题:但重队列中取出数据后,已经使用过的数组元素不能在使用,导致顺序队列不可复用。也可以在每次取出元素后把所有的数据向前移,但这样做带来的开销太大,循环队列是一种好的解决方案。
分析如下:
front
和rear
,与顺序队列不同的是我们将二者的值初始化为0,也就是说front
指向的是头数据,而rear
指向的尾数据的下一个数据。rear==front
public boolean isEmpty() { return rear == front; }
(rear+1)%maxSize=front
。约定:数组中总是有一个位置没有数据,这个位置是当链表已满时rear
指向的位置public boolean isFull() { return (rear + 1) % maxSize == front; }
(real+maxSize-front)%maxSize
public int size() { return (real + maxSize -front) % maxSize; }
完整的代码实现如下
public class CircleArrayQueue { private int maxSize; private int[] arr; private int front; private int rear; public CircleArrayQueue(int maxSize) { this.maxSize = maxSize; arr = new int[maxSize]; } public boolean isEmpty() { return rear == front; } public boolean isFull() { return (rear + 1) % maxSize == front; } public void addQueue(int n) { if (isFull()) { System.out.println("链表已满,不能加入数据"); } arr[rear] = n; rear = (rear + 1) % maxSize; } public int getQueue() { if (isEmpty()) { throw new RuntimeException("队列已空,不能取数据"); } int value = arr[front]; front = (front + 1) % maxSize; return value; } public int headQueue() { if (isEmpty()) { throw new RuntimeException("队列已空,没有数据"); } return arr[front]; } public int size() { return (rear + maxSize - front) % maxSize; } public void list() { if (isEmpty()) { System.out.println("队列已空,没有数据") return; } for (int i = front; i < front + size(); i++) { System.out.printf("arr[%d]=%d\n", i % maxSize, arr[i % maxSize]); } } }