队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出的性质。
入队列:进行插入操作的一端称为队尾
出队列:进行删除操作的一端称为队头
在JAVA中队列和栈不同Stack是一个类,Queue是个接口,底层是通过链表实现的。
队列有以下的方法
方法 | 功能 |
boolean offer(E e) | 入队列 |
E poll() | 出队列 |
peek() | 获取队头元素 |
int size() | 获取队列中有效元素个数 |
boolean isEmpty() | 检测队列是否为空 |
因为Queue是个接口,在实例化时必须实例化LinkedList的对象,因为LinkedList实现了Queue接口。
Queue<Integer> queue1 = new LinkedList<>();
Queue<Integer> queue2 = new LinkedList<>();
循环队列
循环队列就类似将一个数组卷起来变成一个圆环。
可是这也出现了一些问题比如如何判断队列是空还是满?
有三种解决方法:
- 通过添加 size 属性记录
- 保留一个位置
- 使用标记
还有一个问题就是如果发生下面这种情况,我们此时还想再插入一个元素。如何让end指向下标为0的区域呢?
解决方法就是:
(1 + 尾指针所指下标)% 队列长度
代码实现:
class MyCircularQueue {
int[] queue;
int front = 0;
int end = 0;
public MyCircularQueue(int k) {
queue = new int[k+1];
}
public boolean enQueue(int value) {
if (isFull()) {
return false;
}
queue[end] = value;
end = (end+1)%queue.length;
return true;
}
public boolean deQueue() {
if (isEmpty()) {
return false;
}
front = (front+1)%queue.length;
return true;
}
public int Front() {
if (isEmpty()) {
return -1;
}
return queue[front];
}
public int Rear() {
if (isEmpty()) {
return -1;
}
return queue[(end-1+queue.length)%queue.length];
}
public boolean isEmpty() {
return front == end;
}
public boolean isFull() {
return (end + 1) % queue.length == front;
}
}