1,栈的定义

  栈:先进后出的数据结构,如下图所示,先进去的数据在底部,最后取出,后进去的数据在顶部,最先被取出。

      

  栈常用操作:   

s=Stack()         创建栈
s.push(item) 将数据item放在栈的顶部
s.pop() 返回栈顶部数据,并从栈中移除该数据
s.peek() 返回栈顶部数据,但不移除
s.size() 返回栈的大小
s.isEmpty() 返回栈是否为空

  操作示例:

           

2,用python实现栈 

  通过python的list来实现栈,其定义如下面代码所示。其中入栈和出栈操作也可以用insert(0,item)和pop(0),但其时间复杂度为O(n); 而append(item)和pop()时间复杂度为O(1)

class Stack(object):

def __init__(self):
self.items = [] def push(self,item):
self.items.append(item) def pop(self):
return self.items.pop() def peek(self):
return self.items[-1] def size(self):
return len(self.items) def isEmpty(self):
return self.items==[]

3, 栈的应用

  3.1 判断单个括号是否平衡:如下图中的左括号和右括号是否依次匹配

    

              

    利用栈作为数据结构,左括号时入栈,右括号时出栈,相应的代码如下:

from stackDemo import Stack

parentheses = ['((((((())','()))','(()()(()','()()()','(()()']

def check_balence(pString):
s = Stack()
for i in range(len(pString)):
if pString[i]=='(':
s.push(i)
else:
if not s.isEmpty():
s.pop()
else:
return False
return s.isEmpty()
for pt in parentheses:
print check_balence(pt)

  3.2 判断多种括号是否平衡:{ [ ( 和 ) ] }应依次匹配

       平衡示例:

      

       不平衡示例:

       

    实现代码如下:

from stackDemo import Stack
def check_balance(sym_string):
s= Stack()
for i in range(len(sym_string)):
symbol = sym_string[i]
if symbol in '{[(':
s.push(symbol)
else:
if not s.isEmpty():
top = s.pop()
if not match(top,symbol):
return False
else:
return False
return s.isEmpty()
def match(open,close):
opens = '{[('
closes = '}])'
return opens.index(open)==closes.index(close)
symbols = ['{ { ( [ ] [ ] ) } ( ) }','[ [ { { ( ( ) ) } } ] ]','[ ] [ ] [ ] ( ) { }',
'( [ ) ]','( ( ( ) ] ) )','[ { ( ) ]']
for sym_string in symbols:
  sym_string = sym_string.replace(' ','')
  print check_balance(sym_string)

  3.3. 将十进制数转化为二进制数

   过程:将十进制数不断除2,将余数入栈,最后再一次弹出。

   代码实现如下:

from stackDemo import Stack

def divideBy2(decNumber):
s= Stack()
while decNumber>0:
remainder = decNumber%2
s.push(remainder)
decNumber = decNumber//2
binStr = ''
while not s.isEmpty():
binStr = binStr + str(s.pop())
return binStr
print divideBy2(8)

  3.4. 将十进制数转化为二进制,八进制和十六进制数  

  (修改代码便可以转换十进制数为任何base的数字)

from stackDemo import Stack

def baseConvetor(decNumber, base):
s= Stack()
while decNumber>0:
remainder = decNumber%base
s.push(remainder)
decNumber = decNumber//base digits = '0123456789ABCDEF'
binStr = ''
while not s.isEmpty():
binStr = binStr + digits[s.pop()]
if base==8:
return ""+binStr
elif base==16:
return "0x"+binStr
else:
return binStr
print baseConvetor(30,2)
print baseConvetor(30,8)
print baseConvetor(30,16)

  3.5 算术表达式的转换

      一般的算术表达式顺序为Infix Expression,如下表所示,这种形式便于人类理解其执行顺序,但对于电脑,Prefix Expression 和 Postfix Expression 两种形式的表达式更容易理解。需要一个算法程序来完成Infix Expression 到 Prefix Expression 和 Postfix Expression的转换。

    

    Infix Expression 到 Postfix Expression的转换过程:    

      1,新建一个stack来存放运算符,一个list来存放输出结果

      2,对infix expression进行遍历,

        当碰到运算数时将其加入到list末尾

        当碰到左括号时,将其入栈,碰到右括号时,将栈中的内容依次移出并添加到list末尾,直到碰到相应的左括号停止

        当碰到运算符+ - * /时,将其入栈stack,但若栈中有优先度比其高或相同的运算符,先将其移出并添加到list末尾

      3,遍历完成后,将栈中剩余内容依次弹出,添加到list末尾

    代码实现如下:

def infixtopostfix(infix):
prec={'(':1,'+':2, '-':2, '*':3, '/':3}
infix_list = infix.split()
s=Stack()
postfix_list=[]
for item in infix_list:
if item in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or item in "":
postfix_list.append(item)
elif item=='(':
s.push(item)
elif item==')':
top = s.pop()
while top!='(':
postfix_list.append(top)
top = s.pop()
else:
while not s.isEmpty() and (prec[item]<=prec[s.peek()]):
top = s.pop()
postfix_list.append(top)
s.push(item)
while not s.isEmpty():
postfix_list.append(s.pop())
return ' '.join(postfix_list) print infixtopostfix("A * B + C * D")
print infixtopostfix("( A + B ) * C - ( D - E ) * ( F + G )")
print infixtopostfix("( A + B ) * C")
print infixtopostfix("( A + B ) * ( C + D )")

    Postfix Expression的计算过程:

      1,创建一个stack来存放运算数

      2,遍历Postfix Expression

        当碰到运算数时,将其入栈

        当碰到运算符时,出栈两次,若第一次出栈为a,第二次出栈为b,计算 (b 运算符 a),并将结果入栈

      3,遍历完成后,最终的计算结果在栈顶

    代码实现如下:

def postfixEval(postfix):
s = Stack()
postfix_list = postfix.split()
for token in postfix_list:
if token in '':
s.push(int(token))
else:
operand2 = s.pop()
operand1 = s.pop()
result = doMath(operand1,operand2,token)
s.push(result)
return s.pop()
def doMath(operand1,operand2,token):
if token=='*':
return operand1 * operand2
elif token=='/':
return operand1 / operand2
elif token=='+':
return operand1 + operand2
else:
return operand1 - operand2 print postfixEval('5 4 + 8 * 3 2 - 4 2 + * -')
print postfixEval('6 5 + 4 *')

    Infix Expression 到 Prefix Expression: 将Infix Expression 翻转,左右括号互换,然后按infixtopostfix转换,最后再进行翻转?

    过程示例: "( A + B ) * C" — " C * ( B + A )"—"C B A + * "—" * + A B C"

参考:http://interactivepython.org/runestone/static/pythonds/BasicDS/WhatisaStack.html

数据结构之栈(stack)的更多相关文章

  1. Python与数据结构[1] -> 栈/Stack[0] -> 链表栈与数组栈的 Python 实现

    栈 / Stack 目录 链表栈 数组栈 栈是一种基本的线性数据结构(先入后出FILO),在 C 语言中有链表和数组两种实现方式,下面用 Python 对这两种栈进行实现. 1 链表栈 链表栈是以单链 ...

  2. 数据结构之栈(Stack)

    什么是栈(Stack) 栈是一种遵循特定操作顺序的线性数据结构,遵循的顺序是先进后出(FILO:First In Last Out)或者后进先出(LIFO:Last In First Out). 比如 ...

  3. [ACM训练] 算法初级 之 数据结构 之 栈stack+队列queue (基础+进阶+POJ 1338+2442+1442)

    再次面对像栈和队列这样的相当基础的数据结构的学习,应该从多个方面,多维度去学习. 首先,这两个数据结构都是比较常用的,在标准库中都有对应的结构能够直接使用,所以第一个阶段应该是先学习直接来使用,下一个 ...

  4. 数据结构11: 栈(Stack)的概念和应用及C语言实现

    栈,线性表的一种特殊的存储结构.与学习过的线性表的不同之处在于栈只能从表的固定一端对数据进行插入和删除操作,另一端是封死的. 图1 栈结构示意图 由于栈只有一边开口存取数据,称开口的那一端为“栈顶”, ...

  5. Python与数据结构[1] -> 栈/Stack[1] -> 中缀表达式与后缀表达式的转换和计算

    中缀表达式与后缀表达式的转换和计算 目录 中缀表达式转换为后缀表达式 后缀表达式的计算 1 中缀表达式转换为后缀表达式 中缀表达式转换为后缀表达式的实现方式为: 依次获取中缀表达式的元素, 若元素为操 ...

  6. 线性数据结构之栈——Stack

    Linear data structures linear structures can be thought of as having two ends, whose items are order ...

  7. C# 数据结构 栈 Stack

    栈和队列是非常重要的两种数据结构,栈和队列也是线性结构,线性表.栈和队列这三种数据结构的数据元素和元素的逻辑关系也相同 差别在于:线性表的操作不受限制,栈和队列操作受限制(遵循一定的原则),因此栈和队 ...

  8. 【Java数据结构学习笔记之二】Java数据结构与算法之栈(Stack)实现

      本篇是java数据结构与算法的第2篇,从本篇开始我们将来了解栈的设计与实现,以下是本篇的相关知识点: 栈的抽象数据类型 顺序栈的设计与实现 链式栈的设计与实现 栈的应用 栈的抽象数据类型   栈是 ...

  9. 数据结构与算法:栈(Stack)的实现

    栈在程序设计当中是一个十分常见的数据结构,它就相当于一个瓶子,可以往里面装入各种元素,最先装进这个瓶子里的元素,要把后装进这个瓶子里的全部元素拿出来完之后才能够把他给拿出来.假设这个瓶子在桌上平放,左 ...

随机推荐

  1. React的性能优化

    1. 在constructor中绑定事件函数的this指向 把一个函数赋值给一个变量,然后用那个变量去执行函数会造成this的丢失,所以需要绑定this,把绑定放在构造函数中可以保证只绑定一次函数,如 ...

  2. mock.js学习之路一(Vue中使用)

    1.安装mockjs 2.配置mockjs在开发环境中启用,生产环境中禁用 3.创建mock文件夹,以及mock数据文件 4.在main.js中引入与否 5.页面获取数据 testMock(){ th ...

  3. websocket + TP5.1 + apache 配置步骤

    websocket + TP5.1 + apache 配置步骤 1. https ssl配置好 2. 检查php环境是否满足Workerman要求 curl -Ss http://www.worker ...

  4. 《数据结构与算法之美》 <02>复杂度分析(下):浅析最好、最坏、平均、均摊时间复杂度?

    上一节,我们讲了复杂度的大 O 表示法和几个分析技巧,还举了一些常见复杂度分析的例子,比如 O(1).O(logn).O(n).O(nlogn) 复杂度分析.掌握了这些内容,对于复杂度分析这个知识点, ...

  5. Xshell连接阿里云服务被拒绝

    问题描述:突然的Xshell连接阿里云服务被拒绝了(如图)网上众多的方案都不行例如:https://www.cnblogs.com/wanglle/p/11416987.html(参考博文,本人这个问 ...

  6. Python Flask学习笔记(1)

    1.搭建虚拟环境 a. 安装 virtualenv : pip3 install virtualenv b. 建立虚拟环境 : 任意目录下建立一个空文件(我的是 Py_WorkSpace) ,在该文件 ...

  7. 洛谷 P2746 [USACO5.3]校园网Network of Schools (Tarjan,SCC缩点,DAG性质)

    P2746 [USACO5.3]校园网Network of Schools https://www.luogu.org/problem/P2746 题目描述 一些学校连入一个电脑网络.那些学校已订立了 ...

  8. python_tkinter组件摆放方式

    1.最小界面组成 # 导入tkinter模块 import tkinter # 创建主窗口对象 root = tkinter.Tk() # 设置窗口大小(最小值:像素) root.minsize(30 ...

  9. lite-monitor 一款基于shell命令的监控系统

    介绍 lite-monitor 一款基于shell命令的监控系统,可以根据项目中输出的日志定时输出或者统计输出,并发送钉钉机器人报警消息. lite-monitor能做什么: 定时监控某个服务进程是否 ...

  10. H5项目 使用Cropper.js 实现图片 裁剪 操作 (APP端)

    参考地址: 1.https://www.jianshu.com/p/b252a7cbcf0b 2.https://blog.csdn.net/weixin_38023551/article/detai ...