队列
先进先出
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端进行删除操作,而在表的后端进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
就像吃饭排队,先站在队伍里的人先拿到饭😄
API
public class LinkedQueueOfString//储存字符串的队列
LinkedQueueOfString()//创建队列
void enqueue(String item)//入队
String dequeue()//出队列
boolean isEmpty()//判断队列是否为空
示例
空队列什么也没有
push('a')
graph BT
1(a,队头,队尾)push('b')
graph TD
2(a,队头)==>1(b,队尾)push('c')
graph TD
2(b)==>1(c,队尾)
3(a,队头)==>2pop()
graph TD
2(b,队头)==>1(c,队尾)
链表栈
令链表整体方向由队头指向队尾,保存指向队头和队尾元素的引用,可以提高队列出队入队的效率
Code by java
public class LinkedQueueOfString {
private class Node{//内部类
String item;
Node next;//指向下一个结点的引用
}
private Node first,last;//指向队头队尾元素的引用
public boolean isEmpty(){//指向队头元素的引用为空即队列为空
return first==null;
}
public void enqueue(String item){//入队
Node copy=last;//拷贝指向当前队尾元素的引用
last=new Node();//令last重新指向一个新的节点
last.item=item;//对新节点赋值
last.next=null;//新节点的next指向空
if(isEmpty())//如果是队列为空
first=last;//使得队头队尾指向同一个元素
else//不然使得旧的队尾元素的next指向新元素
copy.next=last;
}
public String dequeue(){
String item=first.item;//拷贝当前队头元素的字符串
first=first.next;//让队头指向下一个节点
if(isEmpty())//如果队列为空,使得last指向null
last=null;
return item;//返回旧的队头元素的字符串
}
}
数组队列
数组队列使用一个数组当作队列,好处是节省了空间,缺点是长度固定,有多余空间,而且有下标越界的风险,
q[]
0
1
2
3
4
null
a
b
c
null
队头
队尾
队尾总是指向最后一个元素的后一个元素
enqueue("d")
q[]
0
1
2
3
4
null
a
b
c
d
队尾
队头
size=(队尾-队头+数组长度)%数组长度=(0-1+5)%5=4
dequeue()
q[]
0
1
2
3
4
null
null
b
c
d
队尾
队头
可以看出该数组队列可容纳最大元素个数等于数组长度减一
public class FixedCapacityQueueOfString {
private String[] s;
private int first=0;//队头
private int last=0;//队尾
public FixedCapacityQueueOfString(int capacity) {
s=new String[capacity];//根据capacity分配空间
}
public boolean isEmpty(){//如果队头队尾指向同一个元素说明队列为空
return first==last;
}
public int size(){//循环利用空间
return (last+s.length-first)%s.length;
}
public void enqueue(String item){
s[last]=item;
last=(last+1)%s.length;//循环利用空间
}
public String dequeue(){
String copy=s[first];
s[first]=null;//使得垃圾回收器可以回收一部分空间
first=(first+1)%s.length;
return copy;
}
}
优化-动态数组大小
在入队列时,当队列已满时将数组长度翻倍
在出队列时,当队列元素不足一半数组长度时将数组长度减半