TypeScript 队列实战:从零实现简单、循环、双端、优先队列,附完整测试代码
TypeScript 队列实战从零实现简单、循环、双端、优先队列附完整测试代码引言队列Queue是计算机科学中最基础也最实用的数据结构之一遵循FIFO先进先出原则。在实际开发中从任务调度到消息中间件从广度优先搜索到滑动窗口算法队列无处不在。本文将通过 TypeScript 从零实现四种经典队列并附带完整的单元测试代码帮助你深入理解队列的底层原理。## 1. 简单队列Simple Queue简单队列是最基础的实现支持enqueue入队和dequeue出队操作。我们使用数组作为底层存储。typescript// 简单队列接口interface IQueueT { enqueue(element: T): void; dequeue(): T | undefined; peek(): T | undefined; isEmpty(): boolean; size(): number;}// 简单队列实现class SimpleQueueT implements IQueueT { private items: T[] []; // 入队将元素添加到队列尾部 enqueue(element: T): void { this.items.push(element); } // 出队移除并返回队列头部元素 dequeue(): T | undefined { if (this.isEmpty()) { return undefined; } return this.items.shift(); } // 查看队列头部元素不移除 peek(): T | undefined { if (this.isEmpty()) { return undefined; } return this.items[0]; } // 判断队列是否为空 isEmpty(): boolean { return this.items.length 0; } // 获取队列大小 size(): number { return this.items.length; }}// 测试代码const simpleQueue new SimpleQueuenumber();simpleQueue.enqueue(10);simpleQueue.enqueue(20);simpleQueue.enqueue(30);console.log(简单队列测试:);console.log(出队:, simpleQueue.dequeue()); // 10console.log(队列大小:, simpleQueue.size()); // 2console.log(队列是否为空:, simpleQueue.isEmpty()); // false性能分析简单队列的dequeue操作使用shift()时间复杂度为 O(n)因为数组需要移动后续元素。这在数据量较大时效率较低。## 2. 循环队列Circular Queue循环队列通过复用数组空间解决简单队列的 O(n) 问题使用头尾指针实现 O(1) 的入队和出队。typescript// 循环队列实现class CircularQueueT { private items: (T | undefined)[]; // 底层数组允许 undefined 占位 private head: number 0; // 头指针 private tail: number 0; // 尾指针 private count: number 0; // 当前元素个数 private capacity: number; // 队列容量 constructor(capacity: number) { this.capacity capacity; this.items new Array(capacity).fill(undefined); } // 入队在尾部添加元素 enqueue(element: T): boolean { if (this.isFull()) { console.warn(队列已满无法入队); return false; } this.items[this.tail] element; // 在 tail 位置放入元素 this.tail (this.tail 1) % this.capacity; // 循环移动 tail this.count; return true; } // 出队移除并返回头部元素 dequeue(): T | undefined { if (this.isEmpty()) { return undefined; } const element this.items[this.head]; // 获取头部元素 this.items[this.head] undefined; // 清理空间 this.head (this.head 1) % this.capacity; // 循环移动 head this.count--; return element; } // 判断队列是否为空 isEmpty(): boolean { return this.count 0; } // 判断队列是否已满 isFull(): boolean { return this.count this.capacity; } // 查看头部元素 peek(): T | undefined { return this.items[this.head]; } // 获取当前元素个数 size(): number { return this.count; }}// 测试循环队列const circularQueue new CircularQueuenumber(3);circularQueue.enqueue(1);circularQueue.enqueue(2);circularQueue.enqueue(3);console.log(\n循环队列测试:);console.log(入队 4队列已满:, circularQueue.enqueue(4)); // falseconsole.log(出队:, circularQueue.dequeue()); // 1console.log(再次入队 4:, circularQueue.enqueue(4)); // trueconsole.log(队列状态:);while (!circularQueue.isEmpty()) { console.log(出队:, circularQueue.dequeue()); // 2, 3, 4}核心优势所有操作均为 O(1)适合固定容量的场景如操作系统中的任务队列。## 3. 双端队列Deque双端队列允许在两端进行插入和删除结合了栈和队列的特性。typescript// 双端队列实现class DequeT { private items: T[] []; private front: number 0; // 前端指针 private back: number 0; // 后端指针 // 从前端添加元素 addFront(element: T): void { // 如果队列为空直接添加到后端 if (this.isEmpty()) { this.addBack(element); return; } // 否则在 front 之前插入需要扩展数组 this.front--; // 如果 front 变为负数需要调整数组 if (this.front 0) { this.items.unshift(element); // 在数组头部插入 this.front 0; this.back; } else { this.items[this.front] element; } } // 从后端添加元素 addBack(element: T): void { this.items[this.back] element; this.back; } // 从前端移除元素 removeFront(): T | undefined { if (this.isEmpty()) return undefined; const element this.items[this.front]; this.items[this.front] undefined as any; this.front; if (this.front this.back) { this.front 0; this.back 0; } return element; } // 从后端移除元素 removeBack(): T | undefined { if (this.isEmpty()) return undefined; this.back--; const element this.items[this.back]; this.items[this.back] undefined as any; if (this.front this.back) { this.front 0; this.back 0; } return element; } // 查看前端元素 peekFront(): T | undefined { return this.items[this.front]; } // 查看后端元素 peekBack(): T | undefined { return this.items[this.back - 1]; } isEmpty(): boolean { return this.front this.back; } size(): number { return this.back - this.front; }}// 测试双端队列const deque new Dequenumber();deque.addBack(1);deque.addBack(2);deque.addFront(0);console.log(\n双端队列测试:);console.log(前端元素:, deque.peekFront()); // 0console.log(后端元素:, deque.peekBack()); // 2console.log(移除前端:, deque.removeFront()); // 0console.log(移除后端:, deque.removeBack()); // 2console.log(队列大小:, deque.size()); // 1应用场景双端队列常用于实现撤销操作、滑动窗口最大值问题等。## 4. 优先队列Priority Queue优先队列中的每个元素都有优先级优先级高的元素优先出队。我们使用最小堆作为底层实现。typescript// 优先队列节点interface PriorityNodeT { element: T; priority: number;}// 优先队列实现使用最小堆class PriorityQueueT { private heap: PriorityNodeT[] []; // 入队插入元素并保持堆结构 enqueue(element: T, priority: number): void { const node: PriorityNodeT { element, priority }; this.heap.push(node); this.bubbleUp(this.heap.length - 1); } // 出队移除并返回优先级最高的元素 dequeue(): T | undefined { if (this.isEmpty()) return undefined; const min this.heap[0]; const last this.heap.pop()!; if (!this.isEmpty()) { this.heap[0] last; this.sinkDown(0); } return min.element; } // 上浮操作插入时使用 private bubbleUp(index: number): void { while (index 0) { const parentIndex Math.floor((index - 1) / 2); if (this.heap[index].priority this.heap[parentIndex].priority) { break; } [this.heap[index], this.heap[parentIndex]] [this.heap[parentIndex], this.heap[index]]; index parentIndex; } } // 下沉操作删除时使用 private sinkDown(index: number): void { const length this.heap.length; while (true) { let smallest index; const leftChild 2 * index 1; const rightChild 2 * index 2; if (leftChild length this.heap[leftChild].priority this.heap[smallest].priority) { smallest leftChild; } if (rightChild length this.heap[rightChild].priority this.heap[smallest].priority) { smallest rightChild; } if (smallest index) break; [this.heap[index], this.heap[smallest]] [this.heap[smallest], this.heap[index]]; index smallest; } } isEmpty(): boolean { return this.heap.length 0; } size(): number { return this.heap.length; }}// 测试优先队列const priorityQueue new PriorityQueuestring();priorityQueue.enqueue(紧急任务, 1);priorityQueue.enqueue(普通任务, 3);priorityQueue.enqueue(次要任务, 5);priorityQueue.enqueue(重要任务, 2);console.log(\n优先队列测试:);console.log(出队顺序:);while (!priorityQueue.isEmpty()) { console.log(priorityQueue.dequeue()); // 紧急任务, 重要任务, 普通任务, 次要任务}核心思想最小堆保证根节点始终是优先级最高的元素所有操作时间复杂度为 O(log n)。## 5. 完整测试套件为了验证所有队列的正确性我们编写一个完整的测试函数typescript// 统一测试函数function testQueueT( queue: any, operations: Array{ op: string; args?: any[] }, expected: any[]): void { let result: any[] []; operations.forEach(({ op, args }) { switch (op) { case enqueue: queue.enqueue(...(args || [])); break; case dequeue: result.push(queue.dequeue()); break; case peek: result.push(queue.peek()); break; case size: result.push(queue.size()); break; case isEmpty: result.push(queue.isEmpty()); break; default: break; } }); console.log(测试结果:, JSON.stringify(result)); console.log(预期结果:, JSON.stringify(expected)); const passed JSON.stringify(result) JSON.stringify(expected); console.log(passed ? ✅ 测试通过 : ❌ 测试失败);}// 运行测试console.log( 队列通用测试 );const testQueueInstance new SimpleQueuenumber();testQueue(testQueueInstance, [ { op: enqueue, args: [1] }, { op: enqueue, args: [2] }, { op: dequeue }, { op: enqueue, args: [3] }, { op: dequeue }, { op: dequeue }, { op: isEmpty } ], [1, 2, 3, true]);## 总结通过本文的实战我们使用 TypeScript 实现了四种经典队列1.简单队列基于数组实现简单但出队效率低O(n)2.循环队列通过指针复用空间实现 O(1) 操作适合固定容量场景3.双端队列支持两端操作灵活性强4.优先队列基于最小堆保障高优先级元素优先出队在实际开发中选择哪种队列取决于具体需求- 任务调度系统优先队列- 消息中间件循环队列固定缓冲区- 编辑器撤销功能双端队列- 简单流程控制简单队列掌握这些队列的实现原理不仅能提升你的编码能力还能帮助你更好地理解操作系统、数据库等底层系统的工作原理。希望本文的代码示例能成为你日常开发中的实用参考。

相关新闻

3分钟快速上手PyTorch Geometric:构建你的第一个图神经网络

3分钟快速上手PyTorch Geometric:构建你的第一个图神经网络

3分钟快速上手PyTorch Geometric:构建你的第一个图神经网络 【免费下载链接】pytorch_geometric Graph Neural Network Library for PyTorch 项目地址: https://gitcode.com/GitHub_Trending/py/pytorch_geometric 你是否曾被复杂的图神经网络(GN…

2026/10/16 3:29:44 阅读更多 →
如何在React表单中集成Turnstile:提升安全性的完整指南

如何在React表单中集成Turnstile:提升安全性的完整指南

如何在React表单中集成Turnstile:提升安全性的完整指南 【免费下载链接】react-turnstile Cloudflare Turnstile integration for React. 项目地址: https://gitcode.com/gh_mirrors/re/react-turnstile React Turnstile是Cloudflare Turnstile在React应用中…

2026/10/16 5:11:38 阅读更多 →
Redis-Search终极指南:高性能实时前缀搜索如何革新Rails应用体验

Redis-Search终极指南:高性能实时前缀搜索如何革新Rails应用体验

Redis-Search终极指南:高性能实时前缀搜索如何革新Rails应用体验 【免费下载链接】redis-search Deprecated! High performance real-time prefix search, indexes store in Redis for Rails application 项目地址: https://gitcode.com/gh_mirrors/re/redis-sear…

2026/10/16 5:11:55 阅读更多 →

最新新闻

AI PPT实战:从指令到专业级演示文稿的完整流程与检查清单

AI PPT实战:从指令到专业级演示文稿的完整流程与检查清单

周一晚上十一点,我临时接到一个任务:第二天一早要给团队内部分享一份关于智能家居市场趋势的演示材料。说实在的,以前这种活我一般要预留一个晚上慢慢磨——先想框架,再抠措辞,然后花大量时间调版式、换配色、找图标&a…

2026/10/16 14:46:53 阅读更多 →
BrowserSkill:面向AI时代的浏览器CLI自动化工具

BrowserSkill:面向AI时代的浏览器CLI自动化工具

1. 项目概述:BrowserSkill 是什么,它解决的到底是什么问题?BrowserSkill 这个名字乍一听像某个浏览器插件或 Chrome 扩展,但结合热词中反复出现的bsk、CLI、Chrome、Edge,以及与codex cli、zcode cli、trae cli、devec…

2026/10/16 14:46:53 阅读更多 →
插件系统原理与排障:从Qt平台插件到failed to load plugins实战

插件系统原理与排障:从Qt平台插件到failed to load plugins实战

1. 插件系统:知识工作者的效率杠杆点knowledge-work-plugins 这个名字听起来有点大,但它解决的问题非常具体:一个做知识工作的人,手头少说也有七八种工具——代码编辑器、IDE、笔记软件、命令行终端、文档生成器、绘图工具&#x…

2026/10/16 14:46:53 阅读更多 →
BrowserSkill:用CLI给AI agent装上浏览器操作能力

BrowserSkill:用CLI给AI agent装上浏览器操作能力

1. 从"浏览器自动化"到"给AI装一双手":BrowserSkill到底在解决什么浏览器自动化这件事,做了十几年了。从最早的 Selenium 驱动 WebDriver,到后来的 Puppeteer、Playwright,工具一直在进化,但核心矛…

2026/10/16 14:46:53 阅读更多 →
虚幻引擎角色加速系统:从物理参数到感知体验的完整实现

虚幻引擎角色加速系统:从物理参数到感知体验的完整实现

1. 项目概述:这不是“按住Shift就跑得快”的简单开关在虚幻引擎里做角色移动,很多人卡在第一个坑:明明蓝图里连好了“Add Movement Input”,也设置了“Max Walk Speed”,可角色一加速就飘、一转向就滑、一上坡就原地踏…

2026/10/16 14:46:53 阅读更多 →
STC8G I2C从模式代码调试指南:中断不进、数据错位排查与实战

STC8G I2C从模式代码调试指南:中断不进、数据错位排查与实战

简介:这份资源面向使用STC8G系列单片机进行嵌入式开发的工程师与学习者,聚焦I2C总线从模式的中断编程实践,帮助解决从机响应主机请求、数据收发与错误处理等典型问题。压缩包内共1个文件,为一份C语言源码,整体约1KB&am…

2026/10/16 14:45:52 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →