队列
2021/8/21 23:06:28
本文主要是介绍队列,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
队列介绍
- 队列是一个有序列表,可以使用数组或是链表来实现
- 队列遵循先入先出的原则,即先存入的数据要先取出,后存入的数据要后取出
- 示意图:
数组模拟队列思路
- 队列本身是有序列表,若使用数组的结构来存储队列的数据,则队列数组的声明如下图,其中
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]); } } }
这篇关于队列的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-05并查集详解与实现教程
- 2024-11-05大厂数据结构与算法入门指南
- 2024-11-05大厂算法与数据结构入门指南
- 2024-11-05二叉树入门教程:轻松掌握基础概念与操作
- 2024-11-05红黑树入门教程:从零开始理解红黑树
- 2024-11-05初学者必备:链表基础知识详解
- 2024-11-05平衡树入门教程:理解、构建与应用
- 2024-11-05数据结构入门教程:轻松掌握基础知识
- 2024-11-05数据结构与算法入门教程
- 2024-11-05优先队列入门教程:理解与实现