队列(queue)是一种特殊的线性表 ,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列是按照“先进先出”或“后进后出”的原则组织数据的。队列中没有元素时,称为空队列。
举例:排队结账,第一个进入排队序列的是第一个付完款离开队列的人,而最后进入排队序列排队的是付完款的。
队列分为:
- 单向队列(Queue):只能在一端插入数据,另一端删除数据。
- 双向队列(Deque):每一端都可以进行插入数据和删除数据操作。
单向队列
package yrwan04;
public class MyQueue {
private int[] arr;// 队列的底层实现是一个数组
private int elements;// 实际元素个数
private int front;// 队头
private int rear;// 队尾
// 默认构造一个长度为10的队列
public MyQueue() {
arr = new int[10];
elements = 0;
front = 0;
rear = -1;
}
// 构造一个长度为size的队列
public MyQueue(int size) {
arr = new int[size];
elements = 0;
front = 0;
rear = -1;
}
// 新增数据
public void insert(int value) {
if (!isFull()) {
// 如果队尾指向顶了,那么循环回来,执行队列的第一个元素
if (rear == arr.length - 1) {
rear = -1;
}
elements++;
arr[++rear] = value;// 队尾加1,然后在队尾处插入新的数据
}
}
// 移除数据
public int remove() {
int value = arr[front++];
if (front == arr.length) {
front = 0;
}
elements--;
return value;
}
// 查看队头数据
public int peek() {
return arr[front];
}
// 判断是否为空列
public boolean isEmpty() {
return elements == 0;
}
// 判断是否为满列
public boolean isFull() {
return elements == arr.length;
}
}
测试类:
package yrwan04;
public class MyQueueTest {
public static void main(String[] args) {
MyQueue queue = new MyQueue(4);
queue.insert(1);
queue.insert(2);
queue.insert(3);
queue.insert(4);
System.out.println("isFull?" + queue.isFull());
System.out.println("peek:" + queue.peek());
while (!queue.isEmpty()) {
System.out.println(queue.remove());
}
System.out.println("isEmpty?" + queue.isEmpty());
System.out.println();
queue.insert(1);
queue.insert(2);
queue.insert(3);
queue.insert(4);
while (!queue.isEmpty()) {
System.out.println(queue.remove());
}
}
}
双向队列
双向队列就是一个两端都是结尾或者开头的队列, 队列的每一端都可以进行插入数据项和移除数据项,这些方法可以叫做:
insertRight()、insertLeft()、removeLeft()、removeRight()
- 如果禁止调用insertLeft()和removeLeft()(或右端操作 ),那么双向队列的功能就和栈一样。
- 如果禁止调用insertLeft()和removeRight()(或另一对方法),那么双向队列的功能就和单向队列一样。
总结
单向队列遵循先进先出的原则,而且一端只能插入,另一端只能删除。
双向队列则两端都可插入和删除,如果限制双向队列的某一段的方法,则可以达到和单向队列同样的功能。
栈以及队列的总结:
- 栈、队列(单向队列)通常是用来简化某些程序操作的数据结构,而不是主要作为存储数据的。
- 在这些数据结构中,只有一个数据项可以被访问。
- 栈允许在栈顶压入数据,在栈顶弹出数据,但是只能访问最后一个插入的数据项,也就是栈顶元素。
- 队列(单向队列)只能在队尾插入数据,对头删除数据,并且只能访问对头的数据。而且队列还可以实现循环队列,它基于数组,数组下标可以从数组末端绕回到数组的开始位置。
- 这些数据结构都能由数组实现,但是可以用别的机制(链表、堆等数据结构)实现。