(2)队列与循环队列
队列
队列 (queue) 是一种先进先出的数据结构。 元素被追加到队列末尾, 然后从队列头删除。 在优先队列 (priority queue) 中, 元素被赋予优先级。 当访问元素时, 拥有最高优先级的元素首先被删除。
数组模拟队列思路

代码实现
class ArrayQueue1{ private int maxSize; private int front;//队列头 private int rear;//队列尾 private int[] arr;//模拟队列的数组 //创建队列的构造器 public ArrayQueue1(int arrMaxSize){ maxSize = arrMaxSize; arr = new int[maxSize]; front = -1;//指向队列头部,是指向第一个元素的前一个空位置 rear = -1;//指向队列,就是指向最后一个数据 } //判断队列是否为满 public boolean isFull(){ return rear == maxSize - 1; } //判断队列是否为空 public boolean isEmpty(){ return rear == front; } //判断数据到队列 public void addQueue(int n){ if(isFull()){ System.out.println("队列满"); return; } arr[++rear] =n; } //取出队列第一个的数据 public int getQueue(){ if(isEmpty()){ throw new RuntimeException("队列空"); } front ++;//这里front已经改变了 return arr[front]; } //显示队列第一个的数据 public int headQueue(){ if(isEmpty()){ throw new RuntimeException("队列空"); } return arr[front + 1];//这里只是调取了首位的元素,但是没有改变front的位置 } //获取所有数据(这里的方法是有点问题的) public void showQueue(){ if(isEmpty()){ System.out.println("队列空"); return; } for (int i = 0; i < arr.length ; i++){ System.out.printf("arr[%d]=%d\n",i,arr[i]); } }
数组模拟环形队列
上面的数组使用一次就不能用了,为了达到复用效果,改成环形数列。、
思路:
1. front 变量的含义做一个调整: front 就指向队列的第一个元素, 也就是说 arr[front] 就是队列的第一个元素
front 的初始值 = 0
2. rear 变量的含义做一个调整:rear 指向队列的最后一个元素的后一个位置. 因为希望空出一个空间做为约定.
rear 的初始值 = 0
3. 当队列满时,条件是 (rear + 1) % maxSize == front 【满】
4. 对队列为空的条件, rear == front 空
5. 当我们这样分析, 队列中有效的数据的个数 (rear + maxSize - front) % maxSize // rear = 1 front = 0
图解:


代码实现
修改普通队列的代码为循环队列
class CircleArray { private int maxSize; // 表示数组的最大容量 //front 变量的含义做一个调整: front 就指向队列的第一个元素, 也就是说 arr[front] 就是队列的第一个元素 //front 的初始值 = 0 private int front; //rear 变量的含义做一个调整:rear 指向队列的最后一个元素的后一个位置. 因为希望空出一个空间做为约定. //rear 的初始值 = 0 private int rear; // 队列尾 private int[] arr; // 该数据用于存放数据, 模拟队列 public CircleArray(int arrMaxSize) { maxSize = arrMaxSize; arr = new int[maxSize]; } // 判断队列是否满 public boolean isFull() { return (rear + 1) % maxSize == front; } // 判断队列是否为空 public boolean isEmpty() { return rear == front; } // 添加数据到队列 public void addQueue(int n) { // 判断队列是否满 if (isFull()) { System.out.println("队列满,不能加入数据~"); return; } //直接将数据加入 arr[rear] = n; //将 rear 后移, 一般情况就是rear+1;在循环边界rear+1 = maxSize时,就变回0. rear = (rear + 1) % maxSize; } // 获取队列的数据, 出队列 public int getQueue() { // 判断队列是否空 if (isEmpty()) { // 通过抛出异常 throw new RuntimeException("队列空,不能取数据"); } // 这里需要分析出 front是指向队列的第一个元素 // 1. 先把 front 对应的值保留到一个临时变量 // 2. 将 front 后移, 考虑取模 // 3. 将临时保存的变量返回 int value = arr[front]; front = (front + 1) % maxSize; return value; } // 显示队列的所有数据 public void showQueue() { // 遍历 if (isEmpty()) { System.out.println("队列空的,没有数据~~"); return; } /* * 1.front+size < maxSize,则i= (front~front+size),显然取模后不变。 * 2.front+size > maxSize,即过了队列边界(0),取模可得新一轮的下标 * */ for (int i = front; i < front + size() ; i++) { System.out.printf("arr[%d]=%d\n", i % maxSize, arr[i % maxSize]); } } // 求出当前队列有效数据的个数 public int size() { return (rear + maxSize - front) % maxSize; } // 显示队列的头数据, 注意不是取出数据 public int headQueue() { // 判断 if (isEmpty()) { throw new RuntimeException("队列空的,没有数据~~"); } return arr[front]; } }
Java实例


参考
1. 尚硅谷Java数据结构与java算法(Java数据结构与算法)
2.Java语言程序设计-进阶版(原书第十版).梁勇

浙公网安备 33010602011771号