数据结构与算法(七)--使用链表实现栈
一、前言
之前我们已经学习了链表的所有操作及其时间复杂度分析,我们可以了解到对于链表头的相关操作基本都是O(1)的,例如链表头增加、删除元素,查询元素等等。那我们其实有一个数据结构其实可以完美利用到这些操作的特点,都是在某一段进行操作,那就是栈。本章我们通过链表去实现栈。并且比较用数组实现和用链表实现他们之间的差异。
二、用链表实现栈
2.1、代码实现
那么通过链表实现栈就很简单了,我们知道入栈和出栈都是从链表的同一端进行操作,那么我们只需调用链表的addFirst/removeFirst的方法即可,查找同理。
首先我们将链表栈命名为LinkedListStack,并且实现我们Stack的抽象类,然后设置一个内部属性为我们之前实现的链表,通过该链表完成实现需要重写的方法即可,代码如下:
public class LinkedListStack<T> implements Stack<T> {private LinkedList<T> linkedList;public LinkedListStack() {this.linkedList = new LinkedList<>();}@Overridepublic int getSize() {return linkedList.getSize();}@Overridepublic boolean isEmpty() {return linkedList.isEmpty();}@Overridepublic void push(T t) {linkedList.addFirst(t);}@Overridepublic T pop() {return linkedList.removeFirst();}@Overridepublic T peek() {return linkedList.getFirst();}@Overridepublic String toString() {StringBuilder stringBuilder = new StringBuilder();stringBuilder.append("Stack: top ");stringBuilder.append(linkedList);return stringBuilder.toString();}
}
测试一下:
public static void main(String[] args) {LinkedListStack<Integer> integerArrayStack = new LinkedListStack<>();for (int i = 0; i < 5; i++) {integerArrayStack.push(i);System.out.println(integerArrayStack);}integerArrayStack.pop();System.out.println(integerArrayStack);}
结果没有问题,通过链表实现栈就这样简单的实现了。

2.2、和数组栈比较性能
这个代码和之前数组队列和循环队列效率的对比很接近:
public class TestStackCompare {private static double testQueue(Stack<Integer> s, int opCount){long startTime = System.currentTimeMillis();Random random = new Random();for (int i = 0; i < opCount; i++) {s.push(random.nextInt(Integer.MAX_VALUE));}for (int i = 0; i < opCount; i++) {s.pop();}long endTime = System.currentTimeMillis();return (endTime - startTime)/1000.0;}public static void main(String[] args) {ArrayStack<Integer> integerArrayStack = new ArrayStack<>();LinkedListStack<Integer> integerLinkedListStack = new LinkedListStack<>();System.out.println("arrayStack,time:"+testQueue(integerArrayStack,1000000)+"s");System.out.println("linkedListStack,time:"+testQueue(integerLinkedListStack,1000000)+"s");}
}
那么我们运行下,发现两者效率近乎一致:

当然也有可能得到的结果是有差距的,对于arrayStack来说,时不时就需要扩容,这个对于某些操作系统来说比较耗费时间,而对于linkedListStack来说,它每次new Node就需要不断的开辟空间,这个操作又对于某些操作系统来说更耗费时间;而且这两者的差距会随着操作次数的增多不断拉大,因为扩容并不是每次扩容,而new Node确实是需要每次都new一个,例如我将操作次数放大为10000000次,这个时候两者的时间差距就比较大了:

所以仍然取决于你测试使用的操作系统,配置,jvm版本等等。但是其实我想强调的是,对于数组栈和链表栈来说,他们的各项操作的时间复杂度其实是一致的。他们之间没有复杂度之间的巨大差异。不像数组队列和循环队列,一个6s,一个0.01s,这之间的差距是非常大的。
相关文章:
数据结构与算法(七)--使用链表实现栈
一、前言 之前我们已经学习了链表的所有操作及其时间复杂度分析,我们可以了解到对于链表头的相关操作基本都是O(1)的,例如链表头增加、删除元素,查询元素等等。那我们其实有一个数据结构其实可以完美利用到这些操作的特点,都是在…...
分布式事务详解
摘要 分布式事务主要包括2pc、3pc、消息事务。 2pc指两阶段提交: 第一阶段是准备阶段:所有事务参与者检查执行能力并锁定对应资源,准备完成后将状态告知协调者。第二集段是提交状态:事务参与者全部准备好后,协调者发…...
车载通信架构 —— DDS协议介绍
车载通信架构 —— DDS协议介绍 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和…...
nginx根据不同的客户端设备进行转发请求——筑梦之路
这里主要介绍七层负载方式实现。 环境说明: pc端 web-1 苹果ios端 web-2 安卓Android端 web-3 负载均衡 web-lb 配置示例: pc端: server {listen 9000; #监听9000server_name pc.xxx.com;charset utf-8;location / {root /…...
增强LLM:使用搜索引擎缓解大模型幻觉问题
论文题目:FRESHLLMS:REFRESHING LARGE LANGUAGE MODELS WITH SEARCH ENGINE AUGMENTATION 论文地址:https://arxiv.org/pdf/2310.03214.pdf 论文由Google、University of Massachusetts Amherst、OpenAI联合发布。 大部分大语言模型只会训练一次&#…...
WPF向Avalonia迁移(一、一些通用迁移项目)
通用变更 WPF:Visibility 其他参考文档 WPF: <TextBlock Visibility"Visible"/><TextBlock Visibility"Collapsed"/><TextBlock Visibility"Hidden"/>Avalonia : <TextBlock IsVisib…...
lua学习笔记
单行注释: 多行注释: 命名: Lua不支持下划线大写字母,比如:_ABC 但支持:_abc 关键字: 全局变量: 直接变量名 内容就是全局 局部变量: 加上local即可 nil࿱…...
修改 ModelScope 默认缓存路径
修改 ModelScope 默认缓存路径 设置 MODELSCOPE_CACHE 和 MODELSCOPE_MODULES_CACHE 两个环境变量。 export MODELSCOPE_CACHE<your_favourite_path>/hub export MODELSCOPE_MODULES_CACHE<your_favourite_path>/modelscope_modules完结!...
【ES实战】索引别名的使用说明
索引别名 文章目录 索引别名带有过滤器的别名RoutingWrite Index REST单一添加一个别名示例: 索引创建是增加别名删除别名检索现有别名示例: 索引别名可以通过API的方式进行操作一个索引别名可以映射到一个或一个以上的索引索引名和索引别名不能重复,在集群中都是唯…...
QT信号与槽机制 和 常用控件介绍
QT信号与槽机制 1、信号(signal): 所谓信号槽 (观察者模式)信号本质是事件。信号展现方式就是函数。当某一个事件发生之后,则发出一个信号(signal). 2、槽(slot): 就是对信号响应的函数,槽就是一个函数。槽函数与普通函数区别槽函数可以与一个信号关联&…...
【css-banner图片自适应】
<picture><source media"(max-width: 480px)" srcset"图片地址"><source media"(min-width: 481px)" srcset"图片地址"><img src"图片地址" id"homebanner"></picture>img{height:…...
【k8s管理操作】
k8s管理操作 一、k8s管理操作1.陈述式资源管理2.声明式资源管理 二、k8s基础信息常看(命令)增删改查项目的生命周期:创建-->发布-->更新-->回滚-->删除 headless clusterIP 无头模式 金丝雀发布(Canary Release&#…...
【java基础学习】之DOS命令
#java基础学习 1.常用的DOS命令: dir:列出当前目录下的文件以及文件夹 md: 创建目录 rd:删除目录cd:进入指定目录 cd.. :退回到上级目录 cd\ : 退回到根目录 del:删除文件 exit:退出dos命令行 1.dir:列出当前目录下的文件以及文件夹 2.md: 创建目录 …...
学习记录——StyleGAN2+SA-UNet
SA-UNet for Retinal Vessel improvment using StyleGAN2 作者提出了一种改进视网膜图像分割的方法,通过创建图像及其相应的分割地图来实现。作者的解决方案包括使用DRIVE数据集1对StylGAN2进行训练,并使用目前在分割DRIVE图像方面取得最先进结果的SA-UNet模型对新合成的图像…...
JVM222
文章目录 JVM222运行时数据区的内部结构线程程序计数器(PC寄存器)虚拟机栈 JVM222 运行时数据区的内部结构 概述 本节主要讲的是运行时数据区,也就是下图这部分,它是在类加载器加载完成后的阶段,如下图: …...
C语言 指针
含义 从根本上看,指针是一个值为内存地址的变量(或数据对象)。指针变量的值是地址。 要创建指针变量,先要声明指针变量的类型 作用 1.实现复杂的数据结构,例如数组、链表、队列和堆栈等; 2.能方便地表…...
YOLOv8血细胞检测(7):小目标大目标一网打尽,轻骨干重Neck的轻量级GFPN | 阿里ICLR2022 GiraffeDet
💡💡💡本文改进:小目标大目标一网打尽GFPN,提升大小目标检测性能 GFPN | 亲测在血细胞检测项目中涨点,map@0.5 从原始0.895提升至0.904 收录专栏: 💡💡💡YOLO医学影像检测:http://t.csdnimg.cn/N4zBP ✨✨✨实战医学影像检测项目,通过创新点验证涨点可…...
广度优先(BFS)(例子:迷宫)
广度优先搜索算法(BFS)是一种用于图形和树数据结构的搜索算法。该算法从根节点开始搜索,然后依次访问每个相邻节点。在搜索过程中,每个节点都标记为已访问,以避免重复访问。BFS算法适用于寻找最短路径的问题࿰…...
【安卓源码】安卓Watchdog 机制
在Android系统中,也设计了一个软件层面Watchdog,用于保护一些重要的系统服务,比如:AMS、WMS、PMS等,由于以上核心服务运行在system_server进程里面,所以当以上服务出现异常时,通常会将system_se…...
inscode连接不上gpu,持续8小时,为了数据不丢失续费了6小时,我只想知道什么时候可以连接
并且给我相应的补偿...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门  思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
