数据结构 -- 栈举例

栈是一个线性的有序集合,其中添加移除新项总发生在同一端。这一端通常称为“顶部”。与顶部对应的端称为“底部”。

最近添加的项是最先会被移除的。这种排序原则有时被称为LIFO(Last In First Out),后进先出。它基于在集合内的时间长度做排序。较新的项靠近顶部,较旧的项靠近底部。

栈的底部很重要,因为在栈中靠近底部的项是存储时间最长的。

栈的例子很常见。几乎所有的自助餐厅都有一堆托盘或盘子,你从顶部拿一个,就会有一个新的托盘给下一个客人。想象桌上有一堆书, 只有顶部的那本书封面可见,要看到其他书的封面,只有先移除他们上面的书。

3.3.什么是栈

下图展示了另一个栈,包含了很多 Python 对象。

3.3.什么是栈.primitive

和栈相关的最有用的想法之一来自对它的观察。假设从一个干净的桌面开始,现在把书一本本叠起来,你在构造一个栈。考虑下移除一本书会发生什么。移除的顺序跟刚刚被放置的顺序相反。栈之所以重要是因为它能反转项的顺序。插入跟删除顺序相反,下图展示了 Python 数据对象创建和删除的过程,注意观察他们的顺序。

3.3.什么是栈.simplereversa

想想这种反转的属性,你可以想到使用计算机的时候所碰到的例子。例如,每个 web 浏览器都有一个返回按钮。当你浏览网页时,这些网页被放置在一个栈中(实际是网页的网址)。你现在查看的网页在顶部,你第一个查看的网页在底部。如果按‘返回’按钮,将按相反的顺序浏览刚才的页面。

栈的实现

class Stack:
    def __init__(self):
        self.stack = []

    def isempty(self):
        if len(self.stack) == 0:
            return True
        else:
            return False

    def push(self, item):
        self.stack.append(item)

    def pop(self):
        pop_num = self.stack.pop()
        return pop_num

    def peek(self):
        peek_value = self.stack[-1]
        return peek_value

    def size(self):
        return len(self.stack)

例1. 括号匹配问题

括号匹配意味着每个开始符号具有相应的结束符号,并且括号能被正确嵌套。考虑下面正确匹配的括号字符串:

(()()()())

(((())))

(()((())()))

对比那些不匹配的括号:

((((((())

()))

(()()(()

区分括号是否匹配的能力是识别很多编程语言结构的重要部分。具有挑战的是如何编写一个算法,能够从左到右读取一串符号,并决定括号是否平衡。

为了解决这个问题,我们需要以下的重要观察结果。

  • 从左到右处理符号时,最近开始符号必须与下一个关闭符号相匹配。
  • 处理的第一个开始符号必须等待直到其匹配最后一个符号。结束符号以相反的顺序匹配开始符号。他们从内到外匹配。

3.6.简单括号匹配.simpleparcheck

栈就是解决这个问题很恰当的数据结构,算法是很直接的。

  • 从空栈开始,从左到右处理括号字符串。
  • 如果一个符号是一个开始符号,将其作为一个信号,对应的结束符号稍后会出现。
  • 如果符号是结束符号,则弹出栈,只要弹出栈的开始符号可以匹配结束符号,则括号保持匹配状态。如果任何时候栈上没有出现符合开始符号的结束符号,则字符串不匹配
  • 当所有符号都被处理后,栈应该是空的,如果非空,也表明括号是不匹配的。

代码实现:

s = '(()'
stack = Stack()

for items in s:
    if items == '(':
        stack.push(items)
    else:
        stack.pop()
    a = stack.size()
if stack.size() == 0:
    print(True)
else:
    print(False)

例2. 进制间的相互转换

以10进制转2进制为例

“除 2” 算法假定我们从大于 0 的整数开始。不断迭代的将十进制除以 2,并跟踪余数。第一个除以 2 的余数说明了这个值是偶数还是奇数。偶数有 0 的余数,记为 0。奇数有余数 1,记为 1.我们将得到的二进制构建为数字序列,第一个余数实际上是序列中的最后一个数字。见下图, 我们再次看到了反转的属性,表示栈可能是解决这个问题的数据结构。

3.8.十进制转换成二进制.figure5

代码实现:

stack = Stack()
num = 16
while 1:
    res = num % 2
    stack.push(res)
    num = num / 2

    if num == 0:
        break
bin = ''
for i in range(stack.size()):
    bin += str(stack.pop())
print(bin)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值