基础数据结构队列(queue)的学习与应用
- 什么是队列?
- 应用场景
- 图解原理
- 队列的操作接口
- 顺序队列代码实现
- 循环队列代码实现
什么是队列?
队列是一种“先进先出”(FIFO)的数据结构,是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为对头。队列中没有元素时,称为空队列
应用场景
你有没有过电脑死机,或者游戏卡顿。用户点击是乎都没有用,就当你正要重启电脑或者杀掉游戏时。电脑或手机又恢复了意识,把你刚才的点击的所有操作全部按顺序执行一遍。这其实就是因为操作系统中的多个程序因需要通过一个通道输出而按先后次序派对等待造成的。
再比如,我们向联通客服打电话时,经常听到“现在客服全忙,继续等待请按1,无需等待请挂机”,这也是在他们的通话系统中应用到了队列这种数据结构,来实现排队功能的。
以上可以看出,队列在我们的实际应用中还是很广泛的,下面我们来了解对列的原理和实现
图解原理
队列的操作接口
- 入队(enqueue)
- 出队(dequeue)
- 队空(isEmpty)
- 队满(isFull)
- 队头(front)
队列的接口实现
interface IQueue<T> {
size: number; //队列长度
maxSize: number; //队列最长长度
enqueue(elem: T): boolean; //入列
dequeue(): T; //出列
isEmpty(): boolean; //空
isFull(): boolean; //满
front(): T|undefined; //队列头
}
顺序队列代码实现
// 普通队列
export class Queue<T> {
protected _elems: T[] = [];
protected _maxLength: number = 0;
protected _length: number = 0;
constructor(maxLength: number = Infinity){
this._maxLength = maxLength;
}
get maxSize(): number{
return this._maxLength;
}
get size(): number{
return this._elems.length;
}
//入队
public enqueue(elem: T): boolean{
if(this.isFull()){
return false;
}
this._elems.push(elem);
return true;
}
//出队
public dequeue(): T|undefined{
if(this.isEmpty()){
return undefined;
}
return this._elems.pop();
}
//队空
public isEmpty(): boolean{
return this._elems.length === 0;
}
//队满
public isFull (): boolean {
return this._elems.length === this._maxLength;
}
//队头
public front(): T| undefined{
if(this.isEmpty()){
return undefined;
}
return this._elems[this._elems.length - 1];
}
}
循环队列代码实现
export class CircularQueue<T> {
protected _elem: T[] = [];
protected _head: number = -1;
protected _tail: number = -1;
protected _size: number = 0;
constructor(maxLength: number = Infinity){
this._size = maxLength;
this._head = -1;
this._tail = -1;
}
get size(): number{
if(this._head === -1){
return 0;
}else if(this._head <= this._tail){
return this._tail - this._head + 1;
}else{
return (this._size - this._head) + this._tail + 1;
}
}
get maxSize(): number{
return this._size;
}
//入队
public enQueue(val: T){
if(this.isFull()){
return false;
}
if(this.isEmpty()){
this._head = 0;
}
this._tail = (this._tail + 1)%this._size;
this._elem[this._tail] = val;
return true;
}
//出队
public deQueue(): T|undefined{
if(this.isEmpty()){
return undefined;
}
if(this._head === this._tail){
this._head = this._tail = -1;
return undefined;
}
let head = this._head;
this._head = (this._head + 1)%this._size;
return this._elem[head];
}
//队头
public front(): T{
if(this.isEmpty()){
return undefined;
}
return this._elem[this._head];
}
//队满
public isFull(): boolean{
return ((this._tail + 1)%this._size) === this._head;
}
//队空
public isEmpty(): boolean{
return this._head === -1;
}
}