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. ActiveMQ入门系列一:认识并安装ActiveMQ(Windows下)

    一.什么是ActiveMQ 度娘给出的定义: Apache ActiveMQ是Apache软件基金会所研发的开放源代码消息中间件:由于ActiveMQ是一个纯Java程序,因此只需要操作系统支持Jav ...

  2. 充值css样式

    @charset "utf-8"; /*reset CSS*/ body,ul,ol,dl,dd,h1,h2,h3,h4,h5,h6,figure,form,fieldset,le ...

  3. go module 设置

    国内无法获取被墙的go module,解决方法,设置环境变量 GO111MODULE=on goproxy=https://goproxy.io

  4. DS1302时钟

    采用串行数据传送方式,SPI 3线接口 SPI总线 SPI接口是以主从方式工作的,通常有一个主器件和一个或多个从器件 MOSI – 主器件数据输出,从器件数据输入 MISO – 主器件数据输入,从器件 ...

  5. Spring Data JPA 大纲归纳

    第一天: springdatajpa day1:orm思想和hibernate以及jpa的概述和jpa的基本操作 day2:springdatajpa的运行原理以及基本操作 day3:多表操作,复杂查 ...

  6. C#遍历文件夹下的所有文件

    DirectoryInfo theFolder = new DirectoryInfo(path); DirectoryInfo[] dirInfo = theFolder.GetDirectorie ...

  7. Django_01_创建图书管理项目

    在django中,项目的组织结构为一个项目包含多个应用,一个应用对应一个业务模块 示例:创建项目的名称为test1,完成“图书-英雄”信息的维护,创建应用名称为booktest 创建项目:首先进入到虚 ...

  8. Sublime text3安装

    一.Sublime text3下载 [20190506]下载 官网下载:https://www.sublimetext.com/ https://download.sublimetext.com/Su ...

  9. vscode 远程编辑文件

    操作 安装扩展 remote-vscode 配置ssh 转发: 添加 RemoteForward 52698 127.0.0.1:52698 到 ~/.ssh/config: # Read more ...

  10. 报错Too many connections

    com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establish ...