队列
特征
① 先进先出
② 有一个队列头,队列尾
③ 一般是由数组来实现
单向有限队列:
① 队列头,队列尾 初始值为 -1(
队列头指向第一个元素的前一个位置,队列为尾指向最后一个元素的位置)
② 当front == rear 时队列空
③ 当rear == Maxsize - 1 时队列满
④ 入队列:自增队列尾,放入队列尾自增后的索引位置
⑤ 出队列:自增队列头,返回队列头指向
环形循环队列:
① 队列头,队列为初始值为 0 (
队列头指向第一个元素的位置,队列尾指向最后一个元素的后一个位置)
② 当front == rear 时,队列空
③ 当front ==(rear + 1)% MaxSize 队列满
④ 入队列:把需要存的值放在 rear 索引位置,
rear = (rear + 1) % Maxsize;
⑤ 出队列:临时保存front索引的值,
front = (front + 1) % Maxsize;
⑥ 输出队列
for(int i = front;i < front + (rear - front + Maxsize) % Maxsize; + +i) {
System.out.println(arr[ i % Maxsize]);
}
public class CricleQueue {
public int front;
public int rear;
public int maxsize = 10;
public int[] queueArr;
public CricleQueue() {
this.front = 0;
this.rear = 0;
this.queueArr = new int[this.maxsize];
}
public CricleQueue(int maxSize) {
this.front = 0;
this.rear = 0;
queueArr = new int[maxSize + 1];
}
public boolean isEmpty() {
if (front == rear) {
return true;
} else {
return false;
}
}
public boolean isFull() {
if (front == (rear + 1) % maxsize) {
return true;
} else {
return false;
}
}
public void enter(int id) {
if (isFull()) {
System.out.println("Queue is full.");
return;
}
queueArr[rear] = id;
rear = (rear + 1) % maxsize;
}
public int out() {
if (isEmpty()) {
System.out.println("Queue is empty");
}
int res = queueArr[front];
front = (front + 1) % maxsize;
return res;
}
public void show() {
if (isEmpty()) {
System.out.println("Queue is empty.");
}
for (int i = front; i < front + (rear - front + maxsize) % maxsize; ++i) {
System.out.println(queueArr[i % maxsize]);
}
}
对于队列为何常用数组来实现而不是链表实现的思考:
我们都知道同为线性表数组与链表各有优劣,
数组的优势在于遍历和索引非常的快速,但是在删除与插入的方面效率不如链表。
链表的优势在于插入和删除的效率很高,但是索引和遍历的效果很低。
所以这时能够发现,队列作为频繁涉及出队列和入队列操作的这样一个数据结构,不就刚刚和链表的优势是一致的吗,那为什么又常使用数组来实现队列?
首先要明白的一点就是这一点特性的理解陷阱,插入与删除的频率根本上是和实际情况中总的数据总量变动有关 如果实际总量不会有太大的变化,那么即便使用数组实现队列,也很难涉及到数组扩容及起来带的效率损失。同时,一般情况我们也会用关键字来参与队列的出入,不会让单独的一个结点作为一个属性丰富的对象来参加队列的出入。且在涉及高并发问题时,如果是使用链表实现队列,频繁的出入队列对应着结点频繁的申请空间和释放空间,长期以往造成的内存碎片会非常严重,综上所述,绝大部分情况下队列用数组来实现是最为合适的。