前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数据结构[Python--Stack]

数据结构[Python--Stack]

作者头像
py3study
发布2020-01-07 16:50:33
4000
发布2020-01-07 16:50:33
举报
文章被收录于专栏:python3python3

难得有些许空闲,看一下Python的数据结构--Stack,现将几个典型示例进行总结!

一、什么是栈

     栈是一个有序集合,根据其特性可以称为"先进后出"或"后进先出", 其中添加或删除都发生在同一端,这一端被称为"栈顶",与其对应的叫"栈底"。

    栈的底部很重要,因为其底部存储的数据是时间最长的,最近的添加项总是最先会弹出,这种排序原则有时被称为"LIFO"

二、栈

1. 栈的可用操作

  • Stack() 创建一个空的新栈。 它不需要参数,并返回一个空栈。
  • push(item)将一个新项添加到栈的顶部。它需要 item 做参数并不返回任何内容。
  • pop() 从栈中删除顶部项。它不需要参数并返回item 。栈被修改。
  • top() 从栈返回顶部项,但不会删除它。不需要参数。 不修改栈。
  • isEmpty()测试栈是否为空。不需要参数,并返回布尔值。
  • size() 返回栈中的item 数量。不需要参数,并返回一个整数。
  • clear 清空栈,没有返回值

2. 利用Python 的内置的数据结构List实现栈全部操作

代码语言:javascript
复制
class Stack():
    def __init__(self):
        self.itmes = []
    def isEmpty(self):
        return self.itmes == []
    def clear(self):
        del self.itmes[:]
    def push(self, item):
        self.items.append(item)
    def pop(self):
        return self.itmes.pop()
    def top(self):
        return self.items[-1]
    def size(self):
        return len(self.itmes)

3. 栈的使用示例

3.1 进制转换

代码语言:javascript
复制
class Stack():
    def __init__(self):
        self.itmes = []
    def isEmpty(self):
        return self.itmes == []
    def clear(self):
        del self.itmes[:]
    def push(self, item):
        self.items.append(item)
    def pop(self):
        return self.itmes.pop()
    def top(self):
        return self.items[-1]
    def size(self):
        return len(self.itmes)
def divideBy2(decNumber, base):
    remstack = Stack()
    while decNumber > 0:
        rem = decNumber % base
        remstack.push(rem)
        decNumber = decNumber // base
    binString = ""
    while not remstack.empty():
        binString = binString + str(remstack.pop())
    return binString
if __name__ == '__main__':
    print(divideBy2(42, 2))

说明: 这是用List结构来实现的"栈", 同样我们可以自己写一个栈

3.2 自己写栈

代码语言:javascript
复制
class Node:
    def __init__(self, value):
        self.value = value
        self.next = None
class Stack:
    def __init__(self):
        self.top = None
    def push(self, value):
        node = Node(value)
        node.next = self.top
        self.top = node
    def pop(self):
        node = self.top
        self.top = node.next
        return node.value
s = Stack()
s.push(3)
s.push('ac')
s.push('er')
s.pop()
s.push(5)

说明

  1. 上面所定义的栈,是由top指针指向一个完整的Node实例
  2. 定义一个栈,使用指针控制其读取的位置。

3.3 栈应用--前缀表达式(波兰式)

代码语言:javascript
复制
from __future__ import division
class Node():
    def __init__(self, value):
        self.value = value
        self.next = None
class StackNode():
    def __init__(self):
        self.top = None
    def push(self, value):
        node = Node(value)
        node.next = self.top
        self.top = node
    def pop(self):
        node = self.top
        self.top = node.next
        return node.value
def compute_exec(op, ov1, ov2):
    def add(ov1, ov2):
        return ov1 + ov2
    def sub(ov1, ov2):
        return ov1 - ov2
    def mul(ov1, ov2):
        return ov1 * ov2
    def div(ov1, ov2):
        return ov1 / ov2
    ops = {add: '+', sub: '-', mul: '*', div: "/"}
    for k, v in ops.items():
        if v == op:
            ret = k(ov1, ov2)
            stack1.push(ret)
            break
def perfix_reverse(string):  # reverse
    tmp = ''
    for s in string[::-1]:
        if s == "(":
            tmp += ")"
        elif s == ")":
            tmp += "("
        else:
            tmp += s
    return tmp
def infix_to_prefix(string):
    opt = ''
    string_tmp = perfix_reverse(string)
    for i in string_tmp:  #  前缀表达式
        if i.isdigit():
            opt = i + opt
        elif i != ')':
            stack1.push(i)
        elif i == ")":
            opt = stack1.pop() + opt
            stack1.pop()
    for s in opt[::-1]:
        if s.isdigit():
            stack1.push(s)
        else:
                op1 = s
                ov1 = stack1.pop()
                ov2 = stack1.pop()
                compute_exec(op1, int(ov1), int(ov2))  # compute result 
                continue
    return opt, stack1.pop()
if __name__ == '__main__':
    stack1 = StackNode()  # 操作符
    infix = ['((3+4)*2)', '((3+(4*2))-1)', '(5*(1+2))']
    for i, v in enumerate(infix):
        print infix[i], "==>", infix_to_prefix(v)

说明:

  1. 前缀表达式就是说操作符位于操作数之前
  2. 表达式从右向左依次解析。将数值压栈,遇到符号将栈顶的操作数与次位置弹出进行计算,结果再次入栈,直到表达式解析完成。

3.4 栈应用--后缀表达式(逆波兰式)

代码语言:javascript
复制
class Node():
    def __init__(self, value):
        self.value = value
        self.next = None
class StackNode():
    def __init__(self):
        self.top = None
    def push(self, value):
        node = Node(value)
        node.next = self.top
        self.top = node
    def pop(self):
        node = self.top
        self.top = node.next
        return node.value
def compute_exec(op, ov1, ov2):
    def add(ov1, ov2):
        return ov1 + ov2
    def sub(ov1, ov2):
        return ov1 - ov2
    def mul(ov1, ov2):
        return ov1 * ov2
    def div(ov1, ov2):
        return ov1 / ov2
    ops = {add: '+', sub: '-', mul: '*', div: "/"}
    for k, v in ops.items():
        if v == op:
            ret = k(ov1, ov2)
            stack1.push(ret)
            break
def postfix(expr):
    for s in expr:
        if s.isdigit():
            stack2.push(s)
        elif s != ")":
            stack1.push(s)
        elif s == ")":
            top = stack2.pop()
            snext = stack2.pop()
            stack2.push(''.join([snext, top, stack1.pop()]))
            stack1.pop()
    post_expr = stack2.pop()
    for i in post_expr:
        if i.isdigit():
            stack1.push(i)
        else:
            op = i
            top = stack1.pop()
            snext = stack1.pop()
            compute_exec(op, int(snext), int(top))
    return post_expr, stack1.pop()
if __name__ == '__main__':
    stack1 = StackNode()  # 操作符
    stack2 = StackNode()  # 操作数
    exprs = ['((3+(4*2))-1)', '((3*4)+(3/2))']
    for e in exprs:
        print e, "==>", postfix(e)

说明:

  1.  后缀表达式就是说操作符位于操作数之后。
  2.  表达式从左向右依次解析。将数值压栈,遇到符号将栈顶的操作数与次位置弹出进行计算[次位操作数 栈顶操作数 操作符 ],结果再次入栈,直到表达式解析完成
  3.  计算表达式结果时同样是[次位操作数 操作符 栈顶操作数 ]

四、总结

  1. 以上示例都可以通过http://pythontutor.com/visualize.html#mode=edit 查看程序运行的每一步
  2. 本文参考于https://www.gitbook.com/book/facert/python-data-structure-cn/details
  3. 以上后两个示例代码基于自己理解所写,可能存在bug
  4. 后两个示例的缺点是没有写表达式合法性的检查,表达式的优先级(如表达式无括号可能会导致程序异常)
  5. 此处仅是对栈的一此粗浅理解及应用。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-09-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档