首先准备基本类java
class CircleArray { private int maxSize; //表示队列的最大容量 //front 就指向队列的第一个元素,也就是说arr[front] //front 初始值 0 private int front; //rear 指向队列的最后一个元素的后一个位置 //rear 的初始值 0 private int rear; private int[] arr; //用于存储数据,模拟队列 public CircleArray(int arrMaxSize) { this.maxSize = arrMaxSize; arr = new int[maxSize]; } }
public void addQueue(int n) { //判断队列是否满 if (isFull()) { System.out.println("队列满,不能加入数据!"); return; } //直接将数据加入 arr[rear] = n; //让rear后移,这里必须取模,考虑数组下标越界 rear = (rear + 1) % maxSize; }
rear指向的是队尾元素的后一个位置,与数组大小取模能够解决下标越界问题数组
由于是指向的后一个位置,因此在添加时能够先存入数组,再移动下标数据结构
public int getQueue() { //判断队列是否空 if (isEmpty()) { //经过抛出异常 throw new RuntimeException("队列空,不能取数据"); } int val = arr[front]; front = (front + 1) % maxSize; return val; }
front直接指向的就是队首的位置,由于是循环队列,一样要考虑下标越界this
出队后,要向后移动下标,因此不能直接return出队的元素,先保存出队元素code
再移动front,最后return保存的出队元素索引
public int peekQueue() { //判断 if (isEmpty()) { throw new RuntimeException("队列空,没有数据"); } return arr[front]; }
public int size() { return (rear + maxSize - front) % maxSize; }
须要注意的是:队列
rear的索引在front前面的状况,在普通队列中rear的索引大于front,能够经过简单的rear - front得出元素个数get
可是循环队列会出现rear的索引小于front的状况,简单的相减会出现负数的状况,显然不符合要求,io
利用rear+maxSize可以使rear的索引大于front,而后相减的结果 % maxSize ,class
(rear + maxSize - front) % maxSize == rear - front
public void showQueue() { //遍历 if (isEmpty()) { System.out.println("队列空,没有数据!"); return; } // 思路:从front开始遍历,遍历多少个元素 for (int i = front; i < front + size(); i++) { int index = i % maxSize; System.out.printf("arr[%d]=%d\n", index, arr[index]); } }
思路:算出队列有效元素个数,从front位置开始打印,下标向后移动,取模防止下标越界,循环遍历数组
public boolean isFull() { return (rear + 1) % maxSize == front; }
数组不填满,队首和队尾之间空一个位置,即当元素存储到队列倒数第二个元素时,rear指向最后一个位置,
此时(rear + 1) % maxSize == front
public boolean isEmpty() { return rear == front; }