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. asp.net page类

    1  page 继承自control类 2 httpServerUtility的transfer方法:请求生命周期将在调用此方法之后终止,将不会触发后续的请求生命周期事件,将直接跳到logReques ...

  2. MongoDB——理论及使用命令详解 数据库

    数据存储阶段 文件管理阶段(.txt  .doc .xls) 优点: 1 使用简单,展现直观 2 可以长期保存数据 3 可存储数据量比较大 缺点: 1 查找不方便, 2 容易造成数据冗余, 3 格式不 ...

  3. db2 with用法

    最近在研究db2 递归查询时想到了with,一直以为with只是用来查询递归,但是实际with功能强大,还有更加强大的功能,偶然读到一位大神的文章,对with做了很详细的解读,特贴出来供大家学习研究 ...

  4. [CodeForces 160A] Twins

    题目链接:http://codeforces.com/problemset/problem/160/A 注意排序是从大到小排,不要上来就sort导致从小到大排,细节水题. AC代码: #include ...

  5. java—多线程—notify/notifyAll

    notify应该使用在,只有两个线程在调用类中的两个方法,并在两个方法中进行互斥操作? 博客:Java多线程学习之wait.notify/notifyAll 详解 未完待续……

  6. solr不是自启动,添加code失败

    原文:https://blog.csdn.net/qq_30242987/article/details/100044964 我主要的问题是  conf要复制  configests/sample_t ...

  7. gitlab常用的命令

    git checkout . #本地所有修改的.没有的提交的,都返回到原来的状态git stash  #把所有没有提交的修改暂存到stash里面.可用git stash pop回复.git reset ...

  8. AGC刷题记

    已经刷不了几天了... AGC001 A-BBQ Easy 排个序就过了 B-Mysterious Light 手膜一下,你会发现魔改一下\(gcd\)就行了 C-Shorten Diameter 刚 ...

  9. 【UVALive-7040F】Color

    题目大意:给定一个长度为 N 的序列,现有 M 种颜色,选出一些颜色对这个序列进行染色,要求相邻元素颜色不相同.求最终序列恰好有 K 种不同颜色的染色方案数,结果对1e9+7取模. 题解:二项式反演 ...

  10. 下一代容器技术podman简介

    PODMAN主要由红帽发起和推动,是下一代的容器技术,包括如下三个模块:Podman,Skopeo和Buildah这三个工具都是符合OCI计划下的工具(github/containers).主要是由R ...