TypeScript数据结构与算法(4)最基础的数据结构-循环队列-LoopQueue
在上一篇中,实现的是一个数组队列,但是数组队列的时间复杂度高,在本篇实现了一个循环队列LoopQueue,以下是源码:
/** * Autor: Created by 李清风 on 2020-12-17. * Desc: 数组循环队列(列表),用来提高效率,降低出队、入队的时间复杂度到O(1),关键词:在不移动内部元素的情况下,通过更改front的指向新的队首元素,来降低时间复杂度,front(用来标记队首)tail用来标记队尾,使用%来求余数 */ export class DataStruct_LoopQueue<T> implements Interface_Queue<T>{ private data: T[]; private front: number;//头元素 private tail: number; //标记下一个新元素入队时,应该存储的位置 private size: number; public constructor(capacity: number) { this.data = new Array<T>(capacity + 1); //循环队列,需要有意识的浪费一个单位 this.front = this.tail = this.size = 0; } //获取队列容量大小 public getCapacity(): number { return this.data.length - 1;//减去有意识浪费的那个单位空间 } //获取队列中实际存储的元素个数 getSize(): number { return this.size; } //判断队列是否为空队列 isEmpty(): boolean { return this.front == this.tail; } //入队操作 public enqueue(e: T): void { if ((this.tail + 1) % this.data.length == this.front) { this.resize(this.getCapacity() * 2); } this.data[this.tail] = e; //了解入队操作的本质,就是往队尾添加元素 this.tail = (this.tail + 1) % this.data.length;//设置新的队尾 this.size++;//每次添加新的元素,都要维护下size } //出队操作,时间复杂度O1 public dequeue(): T { if (this.isEmpty()) { throw new Error("DataStruct_LoopQueue is Empty!"); } let ret: T = this.data[this.front];//出队操作本质,就是从队首拿出元素 this.data[this.front] = null; this.front = (this.front + 1) % this.data.length;//设置新的front元素是谁 this.size--; if (this.size == this.getCapacity() / 4 && this.getCapacity() / 2 != 0) { this.resize(this.getCapacity() / 2); } return ret; } //调整队列容量 private resize(expandCount: number) { let newData: T[] = new Array<T>(expandCount + 1); for (let i = 0; i < this.size; i++) { let index = (this.front + i) % this.data.length; newData[i] = this.data[index] } this.data = newData; this.front = 0; this.tail = this.size; } //获取队首元素 public getFront(): T { if (this.isEmpty()) { throw new Error("DataStruct_LoopQueue is Empty!"); } return this.data[this.front]; } }
实现循环队列LoopQueue时,需要的外部知识:求余数的定义,图我放在下面:


浙公网安备 33010602011771号