1.3 环形队列
-
基本介绍
- 在上述队列的基础上进行改动,使这个队列可以重复使用,从而实现环形队列,数组中可预留一个空间?队列的实际长度是数组的长度-1
- front 指向队列头元素 rear 执行队列尾元素的后一个位置
- 队列满的条件 (rear+ 1) % maxSize == front 取模可以防止索引越界
- 队列空的条件 rear == front
- 队列中有效元素的个数 (rear + maxSize - front) % maxSize 取模的作用相当于加取绝对值 随着指针重置,rear - front 可能为负数
-
代码实现
-
public class CircleArrayQueueDemo { public static void main(String[] args) { CircleArrayQueue circleArrayQueue = new CircleArrayQueue(5); char key; Scanner scanner = new Scanner(System.in); a:while (true) { try { System.out.println("q:退出程序"); System.out.println("s:查看队列"); System.out.println("a:向队列中加值"); System.out.println("g:从队列中取值"); System.out.println("h:查看队首元素"); key = scanner.next().charAt(0); switch (key) { case 's': circleArrayQueue.showQueue(); break; case 'a': System.out.println("输入一个值"); circleArrayQueue.addQueue(scanner.nextInt()); break; case 'g': System.out.println("从队列中取出的值为" + circleArrayQueue.getQueue()); break; case 'h': System.out.println("队首元素为" + circleArrayQueue.queueHead()); break; case 'q': scanner.close(); System.out.println("退出程序"); break a; default: System.out.println("命令错误"); } } catch (Exception e) { System.out.println(e.getMessage()); } } } } class CircleArrayQueue { private int maxSize; // 队列的最大容量(此处预留出一个空间,所以队列实际元素数量-1) private int front; // 队列头指针 指向队列头元素 private int rear; // 队列尾指针 指向队列尾元素的后一个位置 private int[] array; // 数组 public CircleArrayQueue(int arrayMaxSize) { // 初始化队列 this.maxSize = arrayMaxSize; this.array = new int[maxSize]; this.front = 0; // 指向队列头元素 this.rear = 0; // 指向队列尾元素的后一个位置 } public boolean isFull() { // 判断队列是否已满(由于队列尾指针指向数组中最后一个位置并且预留出一个空间,所以+1取模) // 取模还不会超出最大索引,相当于重置索引 return (rear + 1) % maxSize == front; } public boolean isEmpty() { return front == rear; // 判断队列是否为空 } public void addQueue(int value) { if (this.isFull()) { throw new RuntimeException("队列已满"); } // 先在队列尾赋值 ,再增加指针的值 取模还不会超出最大索引,相当于重置索引 array[this.rear] = value; this.rear = (this.rear + 1) % maxSize; } public int getQueue() { if (this.isEmpty()) { throw new RuntimeException("队列为空"); } // 先取值 再增加指针的值 所以不能直接返回 需要临时变量 int temp = array[front]; this.front = (this.front + 1) % maxSize;; return temp; } public void showQueue() { if (this.isEmpty()) { throw new RuntimeException("队列为空"); } // 数组中有效数据的个数(也就是队列中有多少元素)(rear + maxSize - front) % maxSize // 展示队列中元素 需要展示从头元素开始 ,遍历多少个(队列中有效元素的个数) // 此处 % 为了计算在数组中的实际位置 for (int i = this.front; i < this.front + size(); i++) { System.out.printf("arr[%d]=%d\t\n", i % maxSize, this.array[i % maxSize]); } } public int size() { // 数组中有效数据的个数(也就是队列中有多少元素) // 此处 使用maxSize 相当于 去绝对值 因为指针重置后 rear - front 可能为负数 return (rear + maxSize - front) % maxSize; } public int queueHead() { if (this.isEmpty()) { throw new RuntimeException("队列为空"); } return this.array[front]; // 显示队首元素 } }