线性表是使用非常广泛的一类数据结构,它对数据的顺序非常敏感,而且它对数据的增删操作非常灵活。在有序排列的数据中,可以灵活的执行增删操作,就好像是为排好队的数据增加了插队的入口。这既是灵活性也是缺陷,原因在于它的灵活性在某种程度上破坏了数据的原始顺序。在某些需要严格遵守数据处理顺序的场景下,我们就需要对线性表予以限制了。经过限制后的线性表,它们通常会被赋予一些新的名字,比如:栈。

什么是栈

栈是特殊的线性表,栈的数据结点必须后进先出。后进的意思是,栈的数据新增操作只能在末端进行,不允许在栈的中间某个结点后新增数据。先出的意思是,栈的数据删除操作也只能在末端进行,不允许在栈的中间某个结点后删除数据。
也就是说,栈的数据新增和删除操作只能在这个线性表的表尾进行,即在线性表的基础上加了限制。如下图所示:

宏观上来看,与数组或链表相比,栈的操作更为受限,那为什么我们要用这种受限的栈呢?其实,单纯从功能上讲,数组或者链表可以替代栈。然而问题是,数组或者链表的操作过于灵活,这意味着,它们过多暴露了可操作的接口。这些没有意义的接口过多,当数据量很大的时候就会出现一些隐藏的风险。一旦发生代码 bug 或者受到攻击,就会给系统带来不可预知的风险。虽然栈限定降低了操作的灵活性,但这也使得栈在处理只涉及一端新增和删除数据的问题时效率更高。

举个实际的例子,浏览器都有页面前进和后退功能,这就是个很典型的后进先出的场景。假设你先后访问了五个页面,分别标记为 1、2、3、4、5。当前你在页面 5,如果执行两次后退,则退回到了页面 3,如果再执行一次前进,则到了页面 4。处理这里的页面链接存储问题,栈就应该是我们首选的数据结构。

栈既然是线性表,那么它也包含了表头和表尾。不过在栈结构中,由于其操作的特殊性,会对表头和表尾的名字进行改造。表尾用来输入数据,通常也叫作栈顶(top);相应地,表头就是栈底(bottom)。栈顶和栈底是用来表示这个栈的两个指针。跟线性表一样,栈也有顺序表示和链式表示,分别称作顺序栈和链栈。

栈的基本操作

如何通过栈这个后进先出的线性表,来实现增删查呢?初始时,栈内没有数据,即空栈。此时栈顶就是栈底。当存入数据时,最先放入的数据会进入栈底。接着加入的数据都会放入到栈顶的位置。如果要删除数据,也只能通过访问栈顶的数据并删除。对于栈的新增操作,通常也叫作 push 或压栈。对于栈的删除操作,通常也叫作 pop 或出栈。对于压栈和出栈,我们分别基于顺序栈和链栈进行讨论

顺序栈

栈的顺序存储可以借助数组来实现。一般来说,会把数组的首元素存在栈底,最后一个元素放在栈顶。然后定义一个 top 指针来指示栈顶元素在数组中的位置。假设栈中只有一个数据元素,则 top = 0。一般以 top 是否为 -1 来判定是否为空栈。当定义了栈的最大容量为 StackSize 时,则栈顶 top 必须小于 StackSize。

当需要新增数据元素,即入栈操作时,就需要将新插入元素放在栈顶,并将栈顶指针增加 1。

删除数据元素,即出栈操作,只需要 top - 1 就可以了。

对于查找操作,栈没有额外的改变,跟线性表一样,它也需要遍历整个栈来完成基于某些条件的数值查找。

链栈

关于链式栈,就是用链表的方式对栈的表示。通常,可以把栈顶放在单链表的头部,如下图所示。由于链栈的后进先出,原来的头指针就显得毫无作用了。因此,对于链栈来说,是不需要头指针的。相反,它需要增加指向栈顶的 top 指针,这是压栈和出栈操作的重要支持。

对于链栈,新增数据的压栈操作,与链表最后插入的新数据基本相同。需要额外处理的,就是栈的 top 指针。如下图所示,插入新的数据,则需要让新的结点指向原栈顶,即 top 指针指向的对象,再让 top 指针指向新的结点。

在链式栈中进行删除操作时,只能在栈顶进行操作。因此,将栈顶的 top 指针指向栈顶元素的 next 指针即可完成删除。对于链式栈来说,新增删除数据元素没有任何循环操作,其时间复杂度均为 O(1)。

对于查找操作,相对链表而言,链栈没有额外的改变,它也需要遍历整个栈来完成基于某些条件的数值查找。

通过分析你会发现,不管是顺序栈还是链栈,数据的新增、删除、查找与线性表的操作原理极为相似,时间复杂度完全一样,都依赖当前位置的指针来进行数据对象的操作。区别仅仅在于新增和删除的对象,只能是栈顶的数据结点。

总结

栈继承了线性表的优点与不足,是个限制版的线性表。限制的功能是,只允许数据从栈顶进出,这也就是栈后进先出的性质。不管是顺序栈还是链式栈,它们对于数据的新增操作和删除操作的时间复杂度都是 O(1)。而在查找操作中,栈和线性表一样只能通过全局遍历的方式进行,也就是需要 O(n) 的时间复杂度。

栈具有后进先出的特性,当你面对的问题需要高频使用新增、删除操作,且新增和删除操作的数据执行顺序具备后来居上的相反关系时,栈就是个不错的选择。例如,浏览器的前进和后退,括号匹配等问题。栈在代码的编写中有着很广泛的应用,例如,大多数程序运行环境都有的子程序的调用,函数的递归调用等。这些问题都具有后进先出的特性。

栈——后进先出的增删改查相关推荐

  1. express+mongodb+vue实现增删改查-全栈之路

    vue element mongodb express 效果图 前言 最近一直想学下node,毕竟会node的前端更有市场.但是光看不练,感觉还是少了点什么,就去github上看别人写的项目,收获颇丰 ...

  2. koa2 mysql增删改查_react+koa2+mysql零门槛的全栈体验,附上完整项目分享

    写在前面 本文适用于对后端开发领域较为陌生的初级前端开发小伙伴,如果你想一个人搞定一整个项目(服务端接口定义开发+前端页面渲染+数据库搭建+服务器搭建+部署上线),希望这篇文章能给你带来一点点参考价值 ...

  3. laravel mysql增删改查_Laravel框架数据库操作的增删改三种方式 阿星小栈

    Laravel提供了3种操作数据库方式:DB facade(原始方式).查询构造器和Eloquent ORM. 数据库的配置文件在config目录下的database.php里.打开这个文件,找到my ...

  4. Java全栈(四)web网页技术:15.书城项目实战四:管理端图书的增删改查(后台)

    1.需求澄清 管理端图书管理页面[book_manager.jsp]页面原型如下: 需要实现图书的添加.删除.修改.分页显示等操作 2.前期准备 2.1 创建数据表books create TABLE ...

  5. python实现四位一并法_python 全栈开发,Day4(列表切片,增删改查,常用操作方法,元组,range,join)...

    一.列表 列表是python中的基础数据类型之一,它是以[]括起来,每个元素以逗号隔开,而且他里面可以存放各种数据类型比如: li = ['alex',123,Ture,(1,2,3,'wusir') ...

  6. servlet增删改查实例_SpringBoot系列(2)整合MongoDB实现增删改查(完整案例)

    自己本科时候一直使用的是Mysql,目前的课题组使用的是MongoDB,因此就花了一部分时间整理了一下,实现springboot与MongoDB的整合,并且实现基本的增删改查操作,从头到尾给出一个完整 ...

  7. ext store 数据修改_Go 数据存储篇(一):基于内存存储实现数据增删改查功能...

    在 Web 编程中,经常需要处理用户请求数据,而用户请求数据的处理往往又涉及到数据存储与获取,支持存储数据的媒介很多,包括内存.文件系统.数据库等,接下来,学院君将花几个篇幅的教程来系统介绍 Go W ...

  8. (数据结构与算法)单链表与双链表增删改查的实现。

    文章目录 链表介绍 1. 单链表应用实例 1.1 实现思路 1.2 代码实现 2.单链表常见面试题 2.1 求单链表中有效节点的个数 2.2 查找单链表中倒数第K个节点 2.3 单链表的反转 2.4 ...

  9. 测试用例 集成测试增删改查_20年高级测试人员的进阶汇总

    软件测试分为初级测试.中级测试.高级测试. 初级测试: 刚刚入行,功能测试是测试工程师的基础功,薪资范围在5K-9K.你可能是应届毕业生,也可能是打算转行进入这个行业,那你必须要掌握这些. 软件测试的 ...

  10. java三年工作经验工资_工作三年还是只会增删改查,Java 程序员如何进阶?

    大部分的企业级应用从本质上看,都是在做增删查改,但是有些公司的业务复杂而专业,有些公司应用的在线用户很多,你做的增删查改和别人做的增删查改,可能会有极大的区别,举个例子: 你做一个新闻资讯网站,首页上 ...

最新文章

  1. [原创]结构在Loadrunner中的应用
  2. 在C/C++语言中使用正则表达式
  3. 数据仓库—stg层_数据仓库之Hive快速入门 - 离线实时数仓架构
  4. Java动物类enjoy方法打印,面向对象编程题汇总
  5. 【qduoj - 1011】数组中出现最多的元素(巧妙方法 或 排序 或 map)
  6. python语言中的数据类型之字典
  7. 排序算法 --- 快速排序
  8. c#中abstract与virtual的区别
  9. Netflix推出《DOTA2》系列动画 3月25日上线
  10. linux系统中存放用户账号信息的文件是,信息安全技术题库:Linux系统中,用户登录密码的hash是存放在()文件中的。...
  11. 实战Swiper:利用Swiper制作手机新闻界面
  12. linux 误删文件夹恢复工具,恢复Linux误删除文件系列之foremost工具
  13. 蜡笔同步 java_蜡笔同步常见问题解析
  14. 计算机文档排版考试,Word和WPS通用的文档排版技巧
  15. 前同事被裁员,股票清零!
  16. 如何裁剪音频文件?裁剪音频的方法有什么?
  17. 文件误删秒恢复!微软又发布了一款命令行神器!
  18. php如何将图片gif,jpg或mysql longblob或blob字段值转换成16进制字符串!编辑
  19. pscp上传文件至服务器
  20. 原生JS利用HTML5 CANVAS画布布局点状连线图

热门文章

  1. 计算机硬件选购与市场调查实验报告,计算机组装与维护实训报告范例-20210527010902.docx-原创力文档...
  2. matlab的方法定义变量,Matlab定义变量怎么操作?定义变量方法介绍
  3. wordpress最佳架构_动物和宠物的24个最佳WordPress主题
  4. 计算机computer英语划分音节,computer是什么意思
  5. 加载mysql驱动失败_java mysql 驱动加载失败
  6. 关于英语单词记忆的总结
  7. 批量读取文件夹下所有excel文件里的内容,放入列表 把所有不管行列名如何excel合并成一个大的excel 批量读取excel,批量合并excel
  8. Jeff Dean三执笔:一文看尽2020年谷歌AI重大突破
  9. 【鑫鑫批量挂Q器 v2.0绿色版】
  10. 京东后台:订单履约系统设计(下)