数据结构之栈(stack)
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)的更多相关文章
- Python与数据结构[1] -> 栈/Stack[0] -> 链表栈与数组栈的 Python 实现
栈 / Stack 目录 链表栈 数组栈 栈是一种基本的线性数据结构(先入后出FILO),在 C 语言中有链表和数组两种实现方式,下面用 Python 对这两种栈进行实现. 1 链表栈 链表栈是以单链 ...
- 数据结构之栈(Stack)
什么是栈(Stack) 栈是一种遵循特定操作顺序的线性数据结构,遵循的顺序是先进后出(FILO:First In Last Out)或者后进先出(LIFO:Last In First Out). 比如 ...
- [ACM训练] 算法初级 之 数据结构 之 栈stack+队列queue (基础+进阶+POJ 1338+2442+1442)
再次面对像栈和队列这样的相当基础的数据结构的学习,应该从多个方面,多维度去学习. 首先,这两个数据结构都是比较常用的,在标准库中都有对应的结构能够直接使用,所以第一个阶段应该是先学习直接来使用,下一个 ...
- 数据结构11: 栈(Stack)的概念和应用及C语言实现
栈,线性表的一种特殊的存储结构.与学习过的线性表的不同之处在于栈只能从表的固定一端对数据进行插入和删除操作,另一端是封死的. 图1 栈结构示意图 由于栈只有一边开口存取数据,称开口的那一端为“栈顶”, ...
- Python与数据结构[1] -> 栈/Stack[1] -> 中缀表达式与后缀表达式的转换和计算
中缀表达式与后缀表达式的转换和计算 目录 中缀表达式转换为后缀表达式 后缀表达式的计算 1 中缀表达式转换为后缀表达式 中缀表达式转换为后缀表达式的实现方式为: 依次获取中缀表达式的元素, 若元素为操 ...
- 线性数据结构之栈——Stack
Linear data structures linear structures can be thought of as having two ends, whose items are order ...
- C# 数据结构 栈 Stack
栈和队列是非常重要的两种数据结构,栈和队列也是线性结构,线性表.栈和队列这三种数据结构的数据元素和元素的逻辑关系也相同 差别在于:线性表的操作不受限制,栈和队列操作受限制(遵循一定的原则),因此栈和队 ...
- 【Java数据结构学习笔记之二】Java数据结构与算法之栈(Stack)实现
本篇是java数据结构与算法的第2篇,从本篇开始我们将来了解栈的设计与实现,以下是本篇的相关知识点: 栈的抽象数据类型 顺序栈的设计与实现 链式栈的设计与实现 栈的应用 栈的抽象数据类型 栈是 ...
- 数据结构与算法:栈(Stack)的实现
栈在程序设计当中是一个十分常见的数据结构,它就相当于一个瓶子,可以往里面装入各种元素,最先装进这个瓶子里的元素,要把后装进这个瓶子里的全部元素拿出来完之后才能够把他给拿出来.假设这个瓶子在桌上平放,左 ...
随机推荐
- Chrome开发者工具中Elements(元素)断点的用途
SAP Engagement Center UI的这个按钮会每秒钟刷新一次,显示页面已经打开了多长时间. 需求:需要找到哪行JavaScript代码不断刷新的按钮文字. 按照经验判断,这个文字肯定是一 ...
- 第二章、Django以及数据库的配置
目录 第二章.Django以及数据库的配置 一.小白必会三板斧 二.静态文件配置 三.form表单 action和method参数可以写的形式 四.request对象及方法 五.django连接数据库 ...
- Ubuntu Nginx Uwsgi Python布置服务器Django项目
1 安装python 3.6 ubuntu预装了2.7,不需要卸载预装库,直接安装python3.6(其实现在的阿里云18.04会给你自动装python2.7.15和3.6.8) 你可以分别查看一下 ...
- Linux下的头文件搜索路径
对于以压缩包发布的软件,在它的目录下通常都有一个配置脚本configure,它的作用确定编译参数(比如头文件位置.连接库位置等),然后生成Makefile以编译程序.可以进入该软件的目录,执 ...
- MySQL开启binlog无法启动ct 10 21:27:31 postfix/pickup[4801]: warning: 6BD991A0039: message has been queue
1 详细异常 ct 10 21:27:31 postfix/pickup[4801]: warning: 6BD991A0039: message has been queue Oct 10 21:2 ...
- Hyperscan简介
Hyperscan是一款来自于Intel的高性能的正则表达式匹配库. 参考 Hyperscan简介
- Linux搭建.net core CI/CD环境
一.简介 微服务开发中自动化.持续化工程十分重要,在成熟的CI/CD环境中项目团队可以灵活分配,大大提供团队效率.如果还不了解什么是CI/CD,可以先查看相关文章,这里主要介绍环境的搭建,相关原理就不 ...
- SSH环境搭建之Spring环境搭建篇
SSH环境搭建之Spring环境搭建篇 一.引入Spring所使用的JAR文件 二.在src目录下创建beans.xml(Spring的容器文件) <?xml version="1.0 ...
- 从后台数据库查询的List数据怎么在前台combobox显示
后台直接从数据库,通过jdbcTemplate查询数据,得到List数据集,里面是Map List<Map<String, Object>> list = jdbcTempl ...
- HTML5新特性——1 HTML5音频
注意:<source>同一个音乐可以添加不同格式的音频,这样就可以满足不同浏览器都能够正常播放,兼容不同浏览器. 代码示例: <!doctype html> <html ...