队列
队列可用链表LinkedList实现、数组实现.
LinkedList 底层是一个双向链表,含有三个域
-
仅实现Queue是普通的队列,从尾进 从头出
-
实现Duque则是一个双端队列,两端都可以进 可以出,因此LinkedList可以是一个双向链表(实现Deque接口),也可以是普通队列(实现Queue接口)
1.链表实现队列
自己实现队列时,我们采用单链表进行实现
class Node{
private int val;
private Node next;
public Node(int val) {
this.val = val;
}
public int getVal() {
return val;
}
public void setVal(int val) {
this.val = val;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
public class 单链表实现队列 {
private Node first;//链表的头
private Node last;//链表的尾
//入队
public void offer(int val) {
//相当于是 尾插法
//需要判断是不是 第一次插入
Node node = new Node(val);
if (this.first==null) {
this.first=node;
this.last=node;
}else {
this.last.setNext(node);
last=node;
}
}
//出队
public int poll() {
//判断当前队列是否为空
if (isEmpty()) {
throw new UnsupportedOperationException("队列为空");
}
int res=this.first.getVal();
this.first=this.first.getNext();
return res;
}
//查看队头元素
public int peek() {
if (this.first==null) {
throw new UnsupportedOperationException("队列为空");
}
return this.first.getVal();
}
//判断队列是否为空
public boolean isEmpty() {
if (this.first==null) {
return true;
}
return false;
}
}
2.循环队列
front 代表当前队头元素下标
rear 代表当前可以存放数据元素的下标
存在的问题
-
当front和rear相遇之后,队列是空还是满?
解决: 浪费一个位置来判断当前队列是空还是满,每次放入新元素时,判断当前rear的下一个是不是front,如果是,则当前队列已经满了
rear的下一个:rear=(rear+1)%length
-
rear下标每次存放完数据之后,还能不能进行 rear=rear+1?
**解决:**不能!!! rear=(rear+1)%length
-
front能不能进行+1操作
**解决:**不能!!! front=(front+1)%length
<🚩 font color=blue,size=3.5> 循环队列为满的判断
rear的下一个是否为font,即 rear+1)%length 是否等于 front,等于则当前队列为满
<🚩 font color=blue,size=3.5> 循环队列为空的判断
rear和front是否相遇,即 rear == front,则当前队列为空
class MyCircularQueue {
private int[] arr;
private int front;//
private int rear;//当前 可以存放元素的下标
public MyCircularQueue(int k) {
this.arr=new int[k];
this.front=0;
this.rear=0;
}
//入队列
public boolean enQueue(int value) {
//当队列为满,返回false
if (isFull()) return false;
this.arr[this.rear]=value;
this.rear=(this.rear+1)%this.arr.length;
return true;
}
//删除队头元素,指向队头的指针到下一个即可
public boolean deQueue() {
//当队列为空,返回false
if (isEmpty()) return false;
this.front=(this.front+1)%this.arr.length;
return true;
}
//查看队头元素
public int Front() {
//当队列为空,返回-1
if (isEmpty()) return -1;
return this.arr[this.front];
}
//查看队尾元素
public int Rear() {
//当队列为空,返回-1
if (isEmpty()) return -1;
int index=(this.rear==0) ? this.arr.length-1:this.rear-1;
return this.arr[index];
}
//判断是否为空
public boolean isEmpty() {
//两指针相遇,则为空
if (this.rear==this.front) {
return true;
}
return false;
}
//判断是否为满
public boolean isFull() {
//rear的下一个位置等于front ,则为满
if ((this.rear+1)%this.arr.length==this.front) {
return true;
}
return false;
}
}