前文传送门:

「一本正经的聊数据结构(1):时间复杂度」

「一本正经的聊数据结构(2):数组与向量」

引言

前一篇内容我们介绍了数组和向量,虽然说向量是数组的一个升级版,但是在另一个维度上,他们都属于线性结构。

那么什么是线性结构呢?

线性结构是一个有序数据元素的集合。常用的线性结构有:线性表,栈,队列,双队列,数组,串。

线性结构是最常用的数据结构,它最大的特点是数据元素之间存在一对一的线性关系。

线性结构拥有两种不同的存储结构,即顺序存储结构和链式存储结构。

顺序存储的线性表称为顺序表,顺序表中的存储元素是连续的。

链式存储的线性表称为链表,链表中的存储元素不一定是连续的,元素节点中存放数据元素以及相邻元素的地址信息。

线性结构中存在两种操作受限的使用场景,就是我们本文要介绍的栈和队列。

至于为什么说栈和队列是受限的线型结构,我们下面细聊。

栈是一种比较奇葩的数据结构,栈的结构是支持对象的插入和删除操作,但是,栈操作的范围仅限于栈的某一特定端,就是下面这样的。

栈遵循先进后出( last-in-first-out, LIFO )的规律,这是重点。

栈一般使用两种方式来实现:

  1. 顺序表:采用顺序存储结构可以模拟栈存储数据的特点,从而实现栈存储结构。

  2. 链表:采用链式存储结构实现栈结构。

注意,这两种实现方式的区别,仅限于数据元素在实际物理空间上存放的相对位置,顺序栈底层采用的是数组,链栈底层采用的是链表。

栈结构我们还是会经常用到,一个非常经典的场景就是在浏览器的后退功能中。

例如我们每次打开一个页面,浏览器都会把这个页面放入栈中,当我们点击后退按钮的时候,在从栈中将这个页面取出来。

顺序栈

顺序栈,是用顺序表实现栈存储结构。

栈存储结构操作数据元素必须遵守 「先进后出 LIFO 」 的原则。

顺序表的底层是使用数组来实现的,简单理解可以直接理解成数组。

只是栈结构对数据的存取过程有特殊的限制,而数组是没有的。

链栈

链栈,是用链表实现栈存储结构。

链表这个结构在前面没聊过,简单画个图大家理解下:

链表的结构相比较数组而言就稍微有些复杂了,链表的每个节点由两部分组成,一个是存放数据的,叫数据域,另一个是存放指针的,叫指针域。

数组在内存中是连续的,所以我们可以轻松的知道数组的每一个元素的位置,而链表在内存中是分散的,我们需要一个指针来指明下一个元素在哪里。

这里介绍的其实是最简单的一种链表,叫单链表,顾名思义,除了单链表之外还有双链表,这个我们有机会后面再聊。

那么链栈是将链表的头部作为栈顶,尾部作为栈底。

将链表头部作为栈顶的一端,可以避免在实现数据 「入栈」 和 「出栈」 操作时做大量遍历链表的耗时操作。

链表的头部作为栈顶,意味着:

  • 在实现数据"入栈"操作时,需要将数据从链表的头部插入。

  • 在实现数据"出栈"操作时,需要删除链表头部的首元节点。

因此,链栈实际上就是一个只能采用头插法插入或删除数据的链表。

Python 实现栈

在 Python 中,栈并不是一个基础数据结构,不过我们可以通过代码来简单的实现它。

因为栈是可以通过两种方式来实现,一种是顺序表,另一种是链表:

首先是最简单的通过顺序表来实现栈,这里使用的是 Python 中的 list 列表:

classStack(object):

def__init__(self):'''        创建空列表实现栈        '''        self.__list = []

defis_empty(self):'''        判断是否为空        :return:        '''return self.__list == []

defpush(self,item):'''        压栈,添加元素        :param item:        :return:        '''        self.__list.append(item)

defpop(self):'''        弹出栈,将元素取出        :return:        '''if self.is_empty():returnelse:return self.__list.pop()

如果不想使用顺序表来实现,还可以使用链表,这里使用的是单链表,链表的结构需要先提前定义:

classNode(object):'''    节点实现    '''def__init__(self,elem):        self.elem = elem        self.next = None

classStack(object):def__init__(self):'''        初始化链表头        '''        self.__head = None

defis_empty(self):return self.__head is None

defpush(self, item):'''        压栈        :param item:        :return:        '''        node = Node(item)        node.next = self.__head        self.__head = node

defpop(self):'''        弹出栈        :return:        '''if self.is_empty():returnelse:            p = self.__head            self.__head = p.nextreturn p.elem

在链表的实现中,我这里先定义了链表的数据结构,然后才定义了栈。

上面两段代码都非常简单,只实现了最简单的两个功能,入栈和出栈,感兴趣的同学可以自己动手实现下。

队列

与栈一样,队列( queue) 也是存放数据对象的一种容器,其中的数据对象也按线性的逻辑次序排列。

队列和栈不一样的地方在于栈是先进后出,而队列是先进先出( first-in-first-out, FIFO )。

同栈一样的是队列也有两种实现方式:

  • 顺序队列:在顺序表的基础上实现的队列结构。

  • 链队列:在链表的基础上实现的队列结构。

Python 中的 Queue

在 Python 的标准库中,Python 为我们提供了线程安全的队列 Queue (总算不用我再自己写个队列了),使用方法异常简单:

先进先出队列 (FIFO) :

import queue

q1 = queue.Queue(maxsize=5)

for i in range(5):q1.put(i)

while not q1.empty():print('q1:',q1.get())

# 结果输出q1: 0q1: 1q1: 2q1: 3q1: 4

Queue 这个标准库中,还为我们提供了 LIFO 队列,即先进后出队列,和我们前面介绍的栈非常类似,翻了下源码,看到是使用 list 实现的,和我们上面的实现基本一致,使用方式如下:

import queue

q2 = queue.LifoQueue(maxsize=5)

for i in range(5):q2.put(i)

while not q2.empty():print('q2:',q2.get())

# 结果输出q2: 4q2: 3q2: 2q2: 1q2: 0

本篇内容就这样了,涉及到的代码肯定会上传代码仓库,有兴趣的同学可以去翻翻看。

示例代码

示例代码-Github:https://github.com/meteor1993/python-learning/tree/master/data_structure

示例代码-Gitee:https://gitee.com/inwsy/python-learning/tree/master/data_structure

感谢阅读

c++数据结构队列栈尸体_一本正经的聊数据结构(3):栈和队列相关推荐

  1. c++数据结构队列栈尸体_数据结构-第三章:栈和队列(栈的应用、括号匹配、表达式转换)...

    第三章:栈和队列 下面讲解栈的应用主要内容有:栈的应用.括号匹配.中 后 前 缀表达式转换 1.栈的应用 1.1括号匹配 我们在数学运算中 [(A+b)*c] - (E-F) 往往都会有[ ] 和 ( ...

  2. 全栈路线_程序员该走全栈路线还是深度专家路线?

    程序员该走全栈路线,还是深度路线?相信这个问题是所有程序员都会思考的一个问题. 先说说何谓全栈?全栈工程师,英文Full Stack engineer,一般是指能独立完成产品开发的人,同时具备前端和后 ...

  3. c++数据结构队列栈尸体_数据结构-栈与队列(二)

    1.设有编号为1,2,3,4 的四辆列车,顺序进入一个栈式结构的站台,如图3.90所示.具体写出这四辆列车开出车站的所有可能的顺序,设栈容量为2. 1234 1243 1324 1342 2134 2 ...

  4. 队列的基本操作_算法设计:数据结构-队列

    一.队列 1.队列的概念 队列是一种"先进先出(first in first out)"的数据结构,它是一种有序线性表的抽象数据类型.队列在计算机 领域的应用也相当的广泛,例如计算 ...

  5. python队列怎么用_如何在Python中使用多处理队列? - python

    我很难理解多处理队列如何在python上工作以及如何实现它.假设我有两个python模块,它们从共享文件中访问数据,我们将这两个模块称为writer和Reader.我的计划是让读取器和写入器都将请求放 ...

  6. 队列的基本操作_算法与数据结构(五) 栈和队列

    ? 工欲善其事,必先利其器. 栈和队列 - Stack And Queue 栈 如何理解栈呢? 后进者先出,先进者后出,这就是典型的 "栈" 结构. 04_栈和队列-栈结构 从栈的 ...

  7. yxc_第二章 数据结构(一)_栈和队列

    目录 一.栈和队列的代码操作 1.AcWing 828 模拟栈 2.AcWing 829 模拟队列 二.单调栈 1.AcWing 830 单调栈 三.单调队列 1.AcWing 154 滑动窗口 一. ...

  8. java使用队列实现栈思路_算法面试:队列实现栈的方案

    声明:码字不易,转载请注明出处,欢迎文章下方讨论交流. 前言:Java数据结构与算法专题会不定时更新,欢迎各位读者监督.本篇介绍的是如何用两个队列实现栈的问题.这道题作为上一篇文章算法面试:栈实现队列 ...

  9. abap判断包含字符当中包含小数点_剑指Offer整理3 -- 栈和队列 + 数学和字符串

    专题3 栈和队列 + 数学和字符串 专题3-1 栈和队列 1. 栈的压入弹出序列 题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字 ...

最新文章

  1. 哪个版本python适用于windows-何种版本的Python适合您
  2. 题目1465:最简真分数
  3. Linux系统的文件句柄数量问题
  4. python反编译工具uncompyle的安装与用法
  5. 用wxpython做ui_单击按钮如何在wxpython中制作其他窗口
  6. oracle 计划名称,甲骨文修改合作伙伴计划 分为四个级别
  7. 54 Django 模型层(1) 单表查询
  8. Androd之在图片右上角显示红色圆圈里面数字提醒
  9. 机器学习必备:前20名Python人工智能和机器学习开源项目
  10. 做计算机工作的要专用手机吗,怎么在手机上完成工作?原来没有电脑手机还可以这样用...
  11. linux一切皆是文件_Linux 的虚拟文件系统(真正理解“一切皆文件”)
  12. mac11.3成功编译taichi笔记
  13. echarts图表随着窗口大小改变自刷新问题解决
  14. 黑白染色——封锁阳光大学
  15. 详解Spring中的CharacterEncodingFilter--forceEncoding为true在java代码中设置失效--html设置编码无效...
  16. mysql常用数据操作之查
  17. ADAMS2016启动证书错误解决
  18. 科学计算机的用途,科学计算器应用介绍及主要用途
  19. 利用谷歌地图模拟地图坐标数据
  20. 配置微软Azure Kinect DK 录制器k4arecorder

热门文章

  1. 【VB】学生信息管理系统6——错误调试
  2. mysql engine innodb myisam 区别
  3. scipy csr_matrix csc_matrix
  4. AICompiler动态shape编译框架
  5. 用OpenCV进行摄像机标定
  6. 新的微芯片MCU增加了来自外部闪存的安全引导保护
  7. 2021年大数据ELK(十一):Elasticsearch架构原理
  8. 2021年大数据Flink(三十七):​​​​​​​Table与SQL ​​​​​​案例四
  9. 【CV】Pytorch一小时教程添加损失函数图像可视化训练过程
  10. Android 模拟机自定义屏幕的尺寸