队列是什么
队列是一种特殊的线性表, 他只允许在表的前端进行删除操作, 在表的后端进行插入操作
只有最早进入队列的元素才能最先从队列中删除, 所以队列又称为 先进先出线性表 (FIFO)
队列的实现
数组实现的队列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| class arrQueue { private queue: unknown[] = [];
enqueue(data: unknown) { return this.queue.push(data); }
dequeue() { return this.queue.shift(); }
front() { return this.queue.at(0); }
isEmpty() { return this.queue.length === 0; } size() { return this.queue.length; } clear() { this.queue = []; } toString() { return this.queue.join("-"); } }
const queue = new arrQueue();
|
数组实现的队列虽然简单, 但是由于 shift 操作消耗资源大, 所以这种队列性能不高
对象实现的队列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| type QueueObj = { [k: number]: any; };
class objectQueue { private queue: QueueObj = {}; private start = 0; private end = 0;
enqueue(data: unknown) { this.queue[this.end] = data; this.end++; return this.queue[this.end - 1]; }
dequeue() { if (this.size() > 0) { let item = this.queue[this.start]; delete this.queue[this.start]; this.start++; return item; } else return undefined; }
front() { return this.queue[this.start]; }
isEmpty() { return this.size() === 0; } size() { return this.end - this.start; } clear() { this.queue = {}; this.start = 0; this.end = 0; } toString() { let str = ""; for (let index = this.start; index < this.end; index++) { str += this.queue[index] + " "; } return str; } }
|
双端队列
双端队列(Double-ended queue,简称 deque)是一种具有队列和栈的性质的数据结构,它允许从两端添加和删除元素。
实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| type DoubleQueue = { [k: number]: any; };
class doubleQueue { private queue: DoubleQueue = {}; private start = 0; private end = 0;
addFront(data: any) { this.start--; this.queue[this.start] = data; return this.queue[this.start]; } addBack(data: unknown) { this.queue[this.end] = data; this.end++; return this.queue[this.end - 1]; } delFront() { if (this.size() > 0) { const item = this.queue[this.start]; delete this.queue[this.start]; this.start++; return item; } else return undefined; }
delBack() { if (this.size() > 0) { const item = this.queue[this.end - 1]; delete this.queue[this.end - 1]; this.end--; return item; } else return undefined; }
peekFront() { return this.queue[this.start]; } peekBack() { return this.queue[this.end - 1]; }
isEmpty() { return this.size() === 0; } size() { return this.end - this.start; } clear() { this.queue = {}; this.start = 0; this.end = 0; } toString() { let str = ""; for (let index = this.start; index < this.end; index++) { str += this.queue[index] + " "; } return str; } }
|
队列的应用
击鼓传花游戏
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| function game(list: Array<string>, num: number) { let queue = new objectQueue(); for (let i = 0; i < list.length; i++) { queue.enqueue(list[i]); }
while (queue.size() > 1) { for (let i = 0; i < num; i++) { queue.enqueue(queue.dequeue()); } console.log(queue.dequeue() + "淘汰了"); } console.log(queue.dequeue() + "胜利"); }
game(["tim", "tom", "jack", "nana", "tina"], 7);
|
检查回文数 (双端队列)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| function check(str: string) { str = str.toLocaleLowerCase().split(" ").join(""); console.log("处理后的字符串:" + str); const que = new doubleQueue(); for (let i = 0; i < str.length; i++) { que.addBack(str[i]); } let tag = true; while (que.size() > 1) { if (que.delFront() != que.delBack()) { tag = false; break; } } console.log(tag); }
check("abc dc bA");
|