目录

  • 一、栈的定义和特性
    • (一)栈的定义
    • (二)栈的反转特性
  • 二、实现分析步骤
  • 三、栈的Python实现代码
  • 四、栈的应用
    • (一)匹配圆括号
    • (二)匹配符号
    • (三)模2除法(十进制转二进制)
    • (四)进制转换
  • 结语

一、栈的定义和特性

(一)栈的定义

栈是一种线性数据结构,栈是元素的有序集合,其元素的顺序取决于添加顺序或移除顺序,它有两端,称作顶端和底端,即对应栈的栈顶栈底,栈中元素的添加称为入栈,而元素的移除称为出栈栈中元素的添加操作和移除操作都发生在其顶端

栈中最后添加的元素将最先被移除,栈的排序原则被称作LIFO,即后进先出,最先添加的元素在栈底,它最后最移出。
简单来说,可比喻为几本书或砖头叠在一起,需要依次从上至下一本一本地拿出书,最下面的那本书最后被拿出。

(二)栈的反转特性

栈的反转特性最明显的例子体现在浏览器的返回键中,我们知道在浏览网页时,实际上的网页是文件,是由 HTML 构成的文件,每个网页文件都有一个唯一的URL(即统一资源定位符)。

当从当前网页跳转到另一个网页页面时,当前浏览的网页处于栈顶,而之前的网页相对当前网页位于栈底,也就是这些网页的URL都被存放在一个栈中。

二、实现分析步骤

通过Python中的类与对象,在类中定义几个方法,且使用列表来实现栈的相关操作,栈的操作有:
1、创建一个空栈,通过构造方法创建一个空列表;

class Stack:def __init__(self):self.items = []  # 创建一个空栈,它不需要参数,且会返回一个空栈

2、向栈(栈顶)中添加元素,通过列表的append()或insert()实现添加新的元素至栈中。(若将列表的尾部作为栈的顶端,则通过append()实现;而若将列表的头部作为栈的顶端,则通过insert()实现,insert()第一个参数表示索引位置,第二个参数即要添加的元素,由于是向栈顶添加元素,则第一个参数为0(列表的下标从0开始));

def push(self, item):self.items.append(item)  # 将一个元素添加到栈的顶端,它需要一个参数item,且无返回值【self.items.insert(0,item)】

3、删除栈顶元素,通过列表的pop()实现删除栈顶的元素。(若将列表的尾部作为栈的顶端,pop()内无参数,即此时删除列表的末尾元素,也就是栈的顶端元素;而若将列表的头部作为栈的顶端,则pop(0)表示移除列表中下标为0的元素);

def pop(self):return self.items.pop()  # 将栈顶的元素移除,它不需要参数,但会返回顶端的元素,且修改栈的内容【return self.items.pop(0)】

4、返回栈顶元素,若将列表的尾部作为栈的顶端,则通过len()先取得列表的长度,由于下标是从0开始,所以要减1;而若将列表的头部作为栈的顶端,则直接通过索引列表下标为0的元素);

def peek(self):return self.items[len(self.items) - 1]  # 返回栈顶端的元素,它不需要参数,不会修改栈的内容【return self.items[0]】

5、检查栈是否为空,通过比较运算符“==”比较栈是否为空,若为空,则返回布尔值False,若不为空,则返回True;

 def isEmpty(self):return self.items == []  # 检查栈是否为空,它不需要参数,且会返回一个布尔值

6、返回栈中元素数目,通过len()取列表的长度,即返回栈中元素的数目。

def size(self):return len(self.items)  # 返回栈中元素的数目,它不需要参数,且会返回一个整数

三、栈的Python实现代码

将列表的尾部作为栈的顶端:

# 通过列表实现栈的操作(以列表尾部作为栈的顶端)
class Stack:def __init__(self):self.items = []  # 创建一个空栈,它不需要参数,且会返回一个空栈def isEmpty(self):return self.items == []  # 检查栈是否为空,它不需要参数,且会返回一个布尔值def push(self, item):self.items.append(item)  # 将一个元素添加到栈的顶端,它需要一个参数item,且无返回值def pop(self):return self.items.pop()  # 将栈顶的元素移除,它不需要参数,但会返回顶端的元素,且修改栈的内容def peek(self):return self.items[len(self.items) - 1]  # 返回栈顶端的元素,它不需要参数,不会修改栈的内容def size(self):return len(self.items)  # 返回栈中元素的数目,它不需要参数,且会返回一个整数s = Stack()  # s是一个新创建的空栈,创建一个对象,即对象名称=类名称()
print(s.isEmpty())  # 检查栈是否为空
s.push("wddd")
s.push("w")
s.push(123)
print(s.peek())  # 返回栈最顶端的元素
print(s.size())  # 返回当前栈中的元素数目
s.push(False)
print(s.size())
print(s.isEmpty())
s.push(0.2)
print(s.pop())  # 删除栈顶元素
print(s.peek())
print(s.size())

运行结果如下:

四、栈的应用

(一)匹配圆括号

我们知道圆括号由左括号“(”和右括号“)”进行匹配的,通过创建一个空栈来保存括号,从左至右依次处理括号,若匹配到左括号则通过push()方法将其添加至栈中,而若匹配到右括号则通过pop()方法删除栈顶元素,最后若所有括号都匹配则栈为空,程序会返回一个布尔值来表示括号是否匹配。
程序完整代码及解析如下:

# 通过列表实现栈的操作(以列表尾部作为栈的顶端)
class Stack:def __init__(self):self.items = []  # 创建一个空栈,它不需要参数,且会返回一个空栈def isEmpty(self):return self.items == []  # 检查栈是否为空,它不需要参数,且会返回一个布尔值def push(self, item):self.items.append(item)  # 将一个元素添加到栈的顶端,它需要一个参数item,且无返回值def pop(self):return self.items.pop()  # 将栈顶的元素移除,它不需要参数,但会返回顶端的元素,且修改栈的内容def peek(self):return self.items[len(self.items) - 1]  # 返回栈顶端的元素,它不需要参数,不会修改栈的内容def size(self):return len(self.items)  # 返回栈中元素的数目,它不需要参数,且会返回一个整数# 定义一个有参函数Par_Checker(),其参数parenthesis是输入的括号
def Par_Checker(parenthesis):s = Stack()  # s是一个新创建的空栈,创建一个对象balanced = Trueindex = 0while index < len(parenthesis) and balanced:  # 若当前索引值小于输入的括号的总长度且变量balanced的值为正确时,一直执行while循环下去symbol = parenthesis[index]# 取输入的括号赋给变量symbol,变量index的初值为0if symbol == "(":  # 若匹配到左括号则通过push()方法将其添加至栈中s.push(symbol)else:if s.isEmpty():  # 检查栈是否为空,它不需要参数,会返回一个布尔值balanced = False  # 栈为空,变量balanced的值变为Falseelse:s.pop()  # 若匹配到右括号则通过pop()方法删除栈顶元素index = index + 1  # 索引加一,对下一个括号进行检查if balanced and s.isEmpty():  # 如果栈为空,则代表所有括号都匹配成功return Trueelse:return False#测试
print(Par_Checker("(()(("))
print(Par_Checker(")(("))
print(Par_Checker("(()(()))"))

运行结果如下:

(二)匹配符号

通过改进匹配圆括号的程序从而实现对符号“()”、“[]”和“{}”的匹配,在原有的基础上加了一个函数matches(),该函数检查每一个从栈顶移除的符合是否与当前的右符合相匹配,匹配符号的程序完整代码及解析如下:

# 通过列表实现栈的操作(以列表尾部作为栈的顶端)
class Stack:def __init__(self):self.items = []  # 创建一个空栈,它不需要参数,且会返回一个空栈def isEmpty(self):return self.items == []  # 检查栈是否为空,它不需要参数,且会返回一个布尔值def push(self, item):self.items.append(item)  # 将一个元素添加到栈的顶端,它需要一个参数item,且无返回值def pop(self):return self.items.pop()  # 将栈顶的元素移除,它不需要参数,但会返回顶端的元素,且修改栈的内容def peek(self):return self.items[len(self.items) - 1]  # 返回栈顶端的元素,它不需要参数,不会修改栈的内容def size(self):return len(self.items)  # 返回栈中元素的数目,它不需要参数,且会返回一个整数# 定义一个有参函数matches(),该函数检查每一个从栈顶移除的符合是否与当前的右符合相匹配
def matches(left, right):left = "([{"right = ")]}"return left.index(left) == right.index(right)  # index()用于检查子字符串是否在字符串中# 定义一个有参函数Par_Checker(),其参数parenthesis是输入的括号
def Par_Checker(parenthesis):s = Stack()  # s是一个新创建的空栈,创建一个对象balanced = Trueindex = 0while index < len(parenthesis) and balanced:  # 若当前索引值小于输入的符号的总长度且变量balanced的值为正确时,一直执行while循环下去symbol = parenthesis[index]  # 取输入的符号赋给变量symbol,变量index的初值为0if symbol in "([{":  # 若匹配到左符号则通过push()方法将其添加至栈中s.push(symbol)else:if s.isEmpty():  # 检查栈是否为空,它不需要参数,会返回一个布尔值balanced = False  # 栈为空,变量balanced的值变为Falseelse:top = s.pop()  # 若匹配到右符号则通过pop()方法删除栈顶元素if not matches(top, symbol):  # 调用matches()函数检查每一个从栈顶移除的符合是否与当前的右符合相匹配,即若未匹配执行以下语句balanced = Falseindex = index + 1  # 索引加一,对下一个符号进行检查if balanced and s.isEmpty():  # 如果栈为空,则代表所有符号都匹配成功return Trueelse:return False#测试
print(Par_Checker("(({)("))
print(Par_Checker("]("))
print(Par_Checker("{([]})"))

运行结果如下:

(三)模2除法(十进制转二进制)

我们知道将十进制转二进制可以通过模2除法的方法实现,也就是除2取余,逆序排列,如下十进制25转换为二进制:

最后可得25=0001 1001=11001:

我们从步骤上可以看出,计算出的第一个余数是得到结果的最后一位,而最后计算出的余数是结果的第一位,所以可以将得到的二进制数看成一系列数字,创建一个空栈,通过一系列方法得到二进制数字。
模2除法的程序完整代码及解析如下:

# 通过列表实现栈的操作(以列表尾部作为栈的顶端)
class Stack:def __init__(self):self.items = []  # 创建一个空栈,它不需要参数,且会返回一个空栈def isEmpty(self):return self.items == []  # 检查栈是否为空,它不需要参数,且会返回一个布尔值def push(self, item):self.items.append(item)  # 将一个元素添加到栈的顶端,它需要一个参数item,且无返回值def pop(self):return self.items.pop()  # 将栈顶的元素移除,它不需要参数,但会返回顶端的元素,且修改栈的内容def peek(self):return self.items[len(self.items) - 1]  # 返回栈顶端的元素,它不需要参数,不会修改栈的内容def size(self):return len(self.items)  # 返回栈中元素的数目,它不需要参数,且会返回一个整数# 创建一个有参函数DivideBy2(),参数为一个十进制数
def DivideBy2(decNumber):s = Stack()  # s是一个新创建的空栈,创建一个对象while decNumber > 0:  # 若输入的十进制大于0,则执行while循环一直下去rem = decNumber % 2  # 参数rem为余数,即十进制数每次除2得到的余数s.push(rem)  # 通过push()方法将得到的余数添加到栈的顶端decNumber = decNumber // 2  # 输入的十进制整数除2,即十进制与2的整数商binString = ""  # 定义一个空字符串binString用于存放二进制数字while not s.isEmpty():  # 若栈不为空,则执行while循环一直下去binString = binString + str(s.pop())  # 通过pop()方法将栈顶的元素移除,通过str()转换为字符串类型并通过"+"拼接赋值给字符串binStringreturn binString  # 得到的二进制值print(DivideBy2(17))
print(DivideBy2(255))
print(DivideBy2(1024))
print(DivideBy2(2022))

运行结果如下:

(四)进制转换

根据十进制转二进制的程序代码可以进一步改进,首先该函数可以另外定义一个参数base,它表示相应的进制数(二进制、八进制、十六进制),另外创建一个字符串digits,由于有十进制转十六进制,所以该字符串的内容应该有ABCDEF,再加上数字0-9,即该字符串的内容为“0123456789ABCDEF”,它用于存储对应位置上的数字,当从栈中移除一个十进制余相应的进制数得到的余数时,就可以作为访问数字的下标,即对应的数字会被添加到结果中,最后再通过pop()方法将栈顶的元素移除,通过对字符串索引的方式依次索引移除的元素,并通过"+"拼接赋值给字符串newString。
十进制转其他进制(二进制、八进制、十六进制)的程序完整代码及解析如下:

# 通过列表实现栈的操作(以列表尾部作为栈的顶端)
class Stack:def __init__(self):self.items = []  # 创建一个空栈,它不需要参数,且会返回一个空栈def isEmpty(self):return self.items == []  # 检查栈是否为空,它不需要参数,且会返回一个布尔值def push(self, item):self.items.append(item)  # 将一个元素添加到栈的顶端,它需要一个参数item,且无返回值def pop(self):return self.items.pop()  # 将栈顶的元素移除,它不需要参数,但会返回顶端的元素,且修改栈的内容def peek(self):return self.items[len(self.items) - 1]  # 返回栈顶端的元素,它不需要参数,不会修改栈的内容def size(self):return len(self.items)  # 返回栈中元素的数目,它不需要参数,且会返回一个整数# 创建一个有参函数BaseConverter(),参数为进制数和进制
def BaseConverter(decNumber, base):digits = "0123456789ABCDEF"  # 创建一个字符串digits,存储对应位置上的数字,当从栈中移除一个余数时,它可以被用作访问数字的下标,对应的数字会被添加到结果中s = Stack()while decNumber > 0:  # 若输入的进制数大于0,则执行while循环一直下去rem = decNumber % base  # 参数rem为余数,即进制数每次除相应的进制得到的余数s.push(rem)  # 通过push()方法将得到的余数添加到栈的顶端decNumber = decNumber // base  # 输入的进制数整数除相应的进制newString = ""  # 定义一个空字符串newString用于存放二进制数字while not s.isEmpty():  # 若栈不为空,则执行while循环一直下去newString = newString + digits[s.pop()]  # 通过pop()方法将栈顶的元素移除,通过对字符串索引的方式依次索引移除的元素,并通过"+"拼接赋值给字符串newStringreturn newString  # 得到的相应进制值#测试
print(BaseConverter(17, 2))
print(BaseConverter(255, 8))
print(BaseConverter(1024, 16))
print(BaseConverter(2022, 16))

运行结果如下:

结语

参考书籍:《Python数据结构与算法分析 第2版》
[美] 布拉德利·米勒(Bradley N. Miller) 戴维·拉努姆(DavidL. Ranum)|译者:吕能 刁寿钧

以上就是本次Python数据结构学习笔记栈的全部内容,篇幅较长,感谢您的阅读和支持,若有表述或代码中有不当之处,望指出!您的指出和建议能给博主带来很大的动力!!!

Python数据结构学习笔记——栈相关推荐

  1. Python数据结构学习笔记——队列和双端队列

    目录 一.队列的定义 二.队列 实现步骤分析 三.队列的Python实现代码 四.队列的应用 六人传土豆游戏 五.双端队列的定义 六.双端队列 实现步骤分析 七.双端队列的Python实现代码 八.双 ...

  2. Python数据结构学习笔记——链表:无序链表和有序链表

    目录 一.链表 二.无序链表 实现步骤分析 三.无序链表的Python实现代码 四.有序链表 实现步骤分析 五.有序链表的Python实现代码 结语 一.链表 链表中每一个元素都由为两部分构成:一是该 ...

  3. 数据结构学习笔记——栈(1)定义理解

    写在前面的话--努力不晚 博主是某985学校数字媒体技术专业的本科在读生,即将成为大四狗,今后打算国内读研. 因为数媒专业设置的缘故,前两年尝试了很多艺术和设计方面的东西:素描.设计原理.UI.视频剪 ...

  4. Python数据结构学习笔记——树和图

    目录 一.树的概念 二.二叉树的实现 (一)列表的列表 (二)结点与引用 三.图的概念 四.图的实现 (一)邻接矩阵 (二)邻接表 一.树的概念 树是一种数据结构,树由结点及连接结点的边组成,每个树有 ...

  5. 数据结构学习笔记——栈和队列

    4 栈与队列   栈是限定仅在表尾进行插入和删除操作的线性表.队列是只允许在一端进行插入操作.而在另一端进行删除操作的线性表. 4.1 栈的定义 栈(stack)是限定仅在表尾进行插入和删除操作的线性 ...

  6. python数据结构学习笔记(五)

    5 Array-Based Sequence 5.2.1 referential arrays 5.2.2 compact arrays in python array.array 5.3 dynam ...

  7. Python数据结构学习笔记——搜索与排序算法

    目录 一.搜索 (一)搜索的方法 (二)顺序搜索 (三)二分搜索 二.排序 内排序和外排序 (一)冒泡排序 (二)选择排序 (三)插入排序 (四)希尔排序 (五)归并排序 (六)快速排序 总结 一.搜 ...

  8. 数据结构学习笔记——栈的基本知识和顺序存储结构实现栈(顺序栈)

    目录 一.栈 (一)栈的概念 (二)栈的排列 (三)共享栈 (四)栈的常见应用 二.顺序栈的定义 三.顺序栈的初始化 四.判断顺序栈是否为空栈 五.判断顺序栈是否为满栈 六.进栈(插入操作) 七.出栈 ...

  9. 408数据结构学习笔记——栈和队列的应用、特殊矩阵的压缩

    目录 1.栈在括号匹配中的应用​ 2.栈在表达式求值中的运用 2.1.中缀表达式转换后缀表达式 2.2.后缀表达式的计算方法 2.3.中缀表达式转换前缀表达式 2.4. 中缀表达式转后缀表达式(机算- ...

最新文章

  1. js 定位当前城市之接口定位(搜狐、新浪、百度、腾讯API)
  2. Spark基础学习笔记11:Scala运算符
  3. 安装工程造价课程设计_安装工程造价课程设计的图纸-上海装修报价
  4. c# DESEncrypt 加密、解密算法
  5. Java的Exception解析
  6. mybatisplus service insert 空指针_c++ 图解层序遍历和逐层打印智能指针建造的二叉树...
  7. 阿里OSS对象存储,实现图片上传进度显示ProgressListener;
  8. C#程序加密工具.Net Reactor教程
  9. python循环抓取图片_【Python系列】第2篇:批量下载图片
  10. Python爬虫_宅男福利?妹纸勿点__一蓑烟雨任平生
  11. 计算机实训学校目的和要求,计算机实习目的和要求
  12. 汉字编码对照表(gb2312/Big5/GB2312)
  13. 分布式系统的完整介绍
  14. ASP.NET学习笔记(二)——一般处理程序之图片上传
  15. shell脚本实战之坦克大战小游戏
  16. 树莓派第一次使用WIN10电脑远程连接(无显示器)
  17. W3C 发布 EME 标准,EFF 退出 W3C
  18. 把我本科2年爬过的坑,送给高考完想要选计算机专业的你,成为人们眼中的大神吧
  19. python3入门笔记
  20. matlab 多子图_matlab 多子图的绘画

热门文章

  1. RabbitMQ Network Partitions
  2. 微软或在开发自己的 CPU、TikTok 发布电视版本、索尼撤下《赛博朋克2077》并为玩家退款|Decode the Week...
  3. 范醒哲:敬畏自然 渴望技术 —— 新冠肺炎后对网络数据传输能力的思考
  4. 探秘云游戏背后实时音视频技术实践
  5. 音视频技术开发周刊 81期
  6. 『每周观察』:“在线抓娃娃”开启新娱乐窗口
  7. nginx源码分析—数组结构ngx_array_t
  8. Hyperledger Fabric 1.0发布:基于区块链的开源分布式账本
  9. RxJava 2.0的基本使用
  10. go语言判断手机号归属地