返回
队列与双端队列:TypeScript实现,从基础到应用
前端
2023-10-30 07:14:26
前言
队列是一种先进先出的数据结构,元素按照进入队列的顺序依次排列,先进入队列的元素先被处理。双端队列是一种特殊的队列,它允许从队首和队尾添加或删除元素。
队列和双端队列在计算机科学中有很多应用,例如:
- 进程调度:操作系统使用队列来调度进程,先进入队列的进程先被执行。
- 消息传递:消息队列用于在进程之间传递消息。
- 数据缓冲:队列用于缓冲数据,以便在需要时使用。
TypeScript实现
队列
class Queue<T> {
private items: T[] = [];
enqueue(item: T): void {
this.items.push(item);
}
dequeue(): T | undefined {
return this.items.shift();
}
peek(): T | undefined {
return this.items[0];
}
isEmpty(): boolean {
return this.items.length === 0;
}
}
双端队列
class Deque<T> {
private items: T[] = [];
enqueueFront(item: T): void {
this.items.unshift(item);
}
enqueueBack(item: T): void {
this.items.push(item);
}
dequeueFront(): T | undefined {
return this.items.shift();
}
dequeueBack(): T | undefined {
return this.items.pop();
}
peekFront(): T | undefined {
return this.items[0];
}
peekBack(): T | undefined {
return this.items[this.items.length - 1];
}
isEmpty(): boolean {
return this.items.length === 0;
}
}
应用
经典问题一:约瑟夫环
约瑟夫环问题是一个经典的计算机科学问题。问题是这样的:有n个人围成一圈,从第一个人开始,依次报数,数到m的人出列,然后从下一个人开始继续报数,直到只剩下一个人。求最后剩下的那个人。
我们可以用队列来解决这个问题。首先,我们将n个人加入队列。然后,从队首开始报数,数到m的人出列。然后,我们将队首的人移动到队尾,继续报数。重复这个过程,直到只剩下一个人。
function josephus(n: number, m: number): number {
const queue = new Queue<number>();
for (let i = 1; i <= n; i++) {
queue.enqueue(i);
}
while (queue.size() > 1) {
for (let i = 0; i < m - 1; i++) {
queue.enqueue(queue.dequeue());
}
queue.dequeue();
}
return queue.dequeue();
}
经典问题二:迷宫问题
迷宫问题是一个经典的计算机科学问题。问题是这样的:给定一个迷宫,求从起点到终点的最短路径。
我们可以用双端队列来解决这个问题。首先,我们将起点加入双端队列。然后,我们将双端队列队首的元素出列,并将其相邻的未访问过的元素加入双端队列。重复这个过程,直到双端队列队尾的元素是终点。
function maze(maze: number[][], start: number[], end: number[]): number[][] {
const queue = new Deque<number[]>();
queue.enqueueFront(start);
while (!queue.isEmpty()) {
const current = queue.dequeueFront();
if (current[0] === end[0] && current[1] === end[1]) {
return queue;
}
const neighbors = getNeighbors(current, maze);
for (const neighbor of neighbors) {
if (!visited(neighbor, queue)) {
queue.enqueueBack(neighbor);
}
}
}
return [];
}
function getNeighbors(current: number[], maze: number[][]): number[][] {
const neighbors: number[][] = [];
if (current[0] > 0 && maze[current[0] - 1][current[1]] === 0) {
neighbors.push([current[0] - 1, current[1]]);
}
if (current[0] < maze.length - 1 && maze[current[0] + 1][current[1]] === 0) {
neighbors.push([current[0] + 1, current[1]]);
}
if (current[1] > 0 && maze[current[0]][current[1] - 1] === 0) {
neighbors.push([current[0], current[1] - 1]);
}
if (current[1] < maze[0].length - 1 && maze[current[0]][current[1] + 1] === 0) {
neighbors.push([current[0], current[1] + 1]);
}
return neighbors;
}
function visited(current: number[], queue: Deque<number[]>): boolean {
for (const item of queue.items) {
if (item[0] === current[0] && item[1] === current[1]) {
return true;
}
}
return false;
}
总结
队列和双端队列是计算机科学中常用的数据结构。本文用TypeScript实现了队列和双端队列,并用其解决了计算机科学领域中的两道经典问题。通过本文,您对队列和双端队列有了更深入的了解,并学习了如何用TypeScript实现它们。