用链表实现队列/栈

简介: 本文介绍如何用链表实现栈和队列,利用双链表头尾操作均为O(1)的特性,通过调用LinkedList API高效实现。栈可选头部或尾部作栈顶,队列同理,只需调整增删位置。文末引出数组实现队列的性能问题,启发优化思考。

用链表实现栈
一些读者应该已经知道该怎么用链表作为底层数据结构实现队列和栈了。因为实在是太简单了,直接调用双链表的 API 就可以了。
注意我这里是直接用的 Java 标准库的 LinkedList,如果你用之前我们实现的 MyLinkedList,也是一样的。
提示
上面这段代码相当于是把双链表的尾部作为栈顶,在双链表尾部增删元素的时间复杂度都是 O(1),符合要求。
当然,你也可以把双链表的头部作为栈顶,因为双链表头部增删元素的时间复杂度也是 O(1),所以这样实现也是一样的。只要做几个修改 addLast -> addFirst,removeLast -> removeFirst,getLast -> getFirst 就行了。
用链表实现队列
同理,用链表实现队列也是一样的,也直接调用双链表的 API 就可以了:
Java
运行代码
复制代码
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
import java.util.LinkedList;

// 用链表作为底层数据结构实现队列
public class MyLinkedQueue {
private final LinkedList list = new LinkedList<>();

// 向队尾插入元素,时间复杂度 O(1)
public void push(E e) {
    list.addLast(e);
}

// 从队头删除元素,时间复杂度 O(1)
public E pop() {
    return list.removeFirst();
}

// 查看队头元素,时间复杂度 O(1)
public E peek() {
    return list.getFirst();
}

// 返回队列中的元素个数,时间复杂度 O(1)
public int size() {
    return list.size();
}

public static void main(String[] args) {
    MyLinkedQueue<Integer> queue = new MyLinkedQueue<>();
    queue.push(1);
    queue.push(2);
    queue.push(3);

    System.out.println(queue.peek()); // 1
    System.out.println(queue.pop()); // 1
    System.out.println(queue.pop()); // 2
    System.out.println(queue.peek()); // 3
}

}
提示
上面这段代码相当于是把双链表的尾部作为队尾,把双链表的头部作为队头,在双链表的头尾增删元素的复杂度都是 O(1),符合队列 API 的要求。
当然,你也可以反过来,把双链表的头部作为队尾,双链表的尾部作为队头。类似栈的实现,只要改一改 list 的调用方法就行了。
文末思考
双链表他比较牛,队列和栈的 API 考不倒它。但是你想一下,数组实现队列的时候,会不会有问题?
队列 API 要求一端增加元素,一端删除元素,而数组的头部无论是增加还是删除元素,时间复杂度都是 O(n)。这种情况下,有没有办法优化呢?
你可以思考一下,下一章我会告诉你答案。

相关文章
|
2月前
|
SQL 人工智能 Linux
SQL Server 2025 正式版发布 - 从本地到云端的 AI 就绪企业数据库
SQL Server 2025 正式版发布 - 从本地到云端的 AI 就绪企业数据库
274 1
SQL Server 2025 正式版发布 - 从本地到云端的 AI 就绪企业数据库
|
1月前
|
Oracle 安全 关系型数据库
Oracle Linux 9.7 发布 - Oracle 提供支持 RHEL 兼容发行版
Oracle Linux 9.7 发布 - Oracle 提供支持 RHEL 兼容发行版
217 114
Oracle Linux 9.7 发布 - Oracle 提供支持 RHEL 兼容发行版
|
2月前
|
Shell Linux 测试技术
Linux Shell循环详解(从零开始掌握Shell脚本中的循环结构)
本文介绍Linux Shell脚本中for和while循环的基本语法与应用,帮助新手掌握自动化任务处理技巧,提升脚本编写效率。
|
3月前
|
缓存 Windows
彻底卸载软件且不留痕!卸载+清理+启动项优化,彻底清理残留信息
一款小巧高效的卸载工具,仅3.85M,主打彻底清理软件残留文件、注册表、服务等。支持强制卸载、应用商店程序移除、浏览器扩展管理、注册表清理、垃圾文件扫描及空文件夹清理,并提供文件粉碎、快捷方式修复等功能,界面简洁且可换肤,是系统清理的得力助手。
298 6
|
3月前
|
机器学习/深度学习 编解码 文字识别
医疗票据OCR图像预处理:印章干扰过滤方案与代码实现
医疗票据OCR技术能自动提取票据中的关键信息,但在实际应用中面临多重挑战。首先,票据版式多样,不同医院、地区的格式差异大,需借助动态模板匹配技术来应对。其次,图像质量参差不齐,存在褶皱、模糊、倾斜、印章遮挡等问题,常通过超分辨率重建和图像修复算法处理。此外,手写体识别、复杂业务逻辑理解(如医疗术语和费用规则)以及数据安全与隐私合规要求也是技术难点。 为应对这些挑战,快瞳系统采用“OCR基础识别 + NLP语义修正”的混合架构,并结合深度学习模型(如CRNN、Transformer)来提升准确率和泛化能力。该技术能显著提升医保报销、保险理赔等场景的效率,是推动医疗信息数字化管理的重要工具。
|
2月前
|
JavaScript 安全 前端开发
智能随访系统源码,如何使用Java Spring Boot,Vue,Ant Design快速开发一套医院随访系统
基于Spring Boot + Vue + Ant Design Vue技术栈开发的医疗随访系统,涵盖患者管理、随访计划与执行、统计报表及系统管理模块。前后端分离架构,支持多渠道随访,数据安全可控,具备良好的扩展性与开发效率。
179 0
|
10天前
|
缓存 NoSQL Redis
千万级数据表的count(*)查询优化
针对千万级数据表`user_factor_auth_record`的COUNT查询性能问题,可通过“避免实时计数、独立计数表、Redis缓存”三大方案优化。优先从业务层面取消总条数展示,减轻数据库压力;若需精确值,可借助事务维护独立计数表,或定时缓存至Redis,分摊开销、提升查询效率。
89 5
|
9天前
|
人工智能 安全 搜索推荐
钉钉发布全球首个工作智能操作系统Agent OS,专为AI打造
钉钉发布AI钉钉1.1“木兰”版本,推出全球首个为AI打造的工作智能操作系统Agent OS,带来DingTalk Real、钉钉ONE等创新产品,全面升级AI搜问、AI表格、AI听记等应用,开启人与AI协同的全新工作方式。
87 0
钉钉发布全球首个工作智能操作系统Agent OS,专为AI打造
|
2月前
|
存储 Web App开发 前端开发
新手如何建站.新手建站的全流程
建站是通过整合域名、服务器等要素搭建可访问数字平台的过程,分自助建站、CMS系统和代码开发三类工具。核心流程包括需求规划、域名注册(实名认证)、服务器配置(国内需ICP备案),搭建后填充内容并测试优化,解析域名上线,做好后续维护。
244 10
|
1月前
|
Oracle 关系型数据库 Linux
Oracle Linux 10.1 发布 - Oracle 提供支持 RHEL 兼容发行版
Oracle Linux 10.1 发布 - Oracle 提供支持 RHEL 兼容发行版
98 0
Oracle Linux 10.1 发布 - Oracle 提供支持 RHEL 兼容发行版