-
什么是栈?
栈是一种先进先出的存储器,只可以通过一个入口访问其中的数据项。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
-
如何在Python中实现栈及其基本操作?
Python中的数据结构相对于C和C++来说实在简单了太多,底层的实现都不需要,只需要调用每种数据结构所对应操作所对应的函数即可。下列代码段是其底层实现。
```python
class Stcak:
def __init__(self):
self.items = []
#判断栈是否为空
def inEmpty(self):
return self.items ==[] #栈中的元素是否为空
#向栈中压入元素
def push(self,item):
self.items.append(item)
#元素出栈
def pop(self):
return self.items.pop()
#取出栈底元素
def peek(self):
return self.items[len(self.items) - 1]
#获得栈的长度
def size(self):
return len(self.items)
- 几个栈应用的小例子:
3.1 实现通用括号匹配算法:
问题背景:在实际编程的过程中,我们需要判断叠加的括号左右半边括号是否完整,以及在html中各标签和结束标签是否完整,对于该类问题即可通过栈操作来解决。
from pythonds.basic.stack import Stack
def parChecker(SymbolString):
#创建一个新的栈
s = Stack()
#是否平衡的初始状态设为True
balanced = True
index = 0
while index < len(SymbolString) and balanced:
#从第一个符号开始遍历
symbol = SymbolString[index]
#如果是三种符号中的一种,压栈
if symbol in "([{":
s.push(symbol)
else:
#如果不是,判断栈是否为空
if s.isEmpty():
balanced = False
else:
top = s.pop()
#如果仍存在元素,且与该元素不一致则说明有落单的括号
if not matches(top,symbol):
balanced = False
index = index + 1
if balanced and s.isEmpty():
return True
else:
return False
def matches(open,close):
open = "([{"
close = "}])"
return open.index(open) == close.index(close)
print(parChecker('[{[{()}]}]'))
print(parChecker('[{[{]]]'))
class Stack(object):
def __init__(self, limit=10):
self.stack = [] #存放元素
self.limit = limit #栈容量极限
def push(self, data): #判断栈是否溢出
if len(self.stack) >= self.limit:
print('StackOverflowError')
pass
self.stack.append(data)
def pop(self):
if self.stack:
return self.stack.pop()
else:
raise IndexError('pop from an empty stack') #空栈不能被弹出
def peek(self): #查看堆栈的最上面的元素
if self.stack:
return self.stack[-1]
def is_empty(self): #判断栈是否为空
return not bool(self.stack)
def size(self): #返回栈的大小
return len(self.stack)
def balanced_parentheses(parentheses):
stack = Stack(len(parentheses))
for parenthesis in parentheses:
if parenthesis == '(':
stack.push(parenthesis)
elif parenthesis == ')':
if stack.is_empty():
return False
stack.pop()
return stack.is_empty()
if __name__ == '__main__':
examples = ['((()))', '((())', '(()))']
print('Balanced parentheses demonstration:\n')
for example in examples:
print(example + ': ' + str(balanced_parentheses(example)))
3.2 十进制数转换成N进制的数的实现
问题背景:十进制数转换成N进制数,只需要去除以N后再取余,一直到余数为零,然后再将余数反转,即可得到N进制数。该过程的实现代码如下:
from pythonds.basic.stack import Stack
def baseConverter(decNum, base):
digits = "0123456789ABCDEF"
remstack = Stack()
while decNum > 0:
rem = decNum % base
remstack.push(rem)
decNum = decNum // base
newString = ""
while not remstack.isEmpty():
newString = newString + digits[remstack.pop()]
return newString
print(baseConverter(25,2))
print(baseConverter(25,16))
3.3 将表达式由中序遍历改为后序遍历
例如A+(B+CD)即可表示为ABCD++,其实现代码如下:
from pythonds.basic.stack import Stack
def infixToPostfix(infixexpr):
#定义优先级
prec = {}
prec["*"] = 3
prec["/"] = 3
prec["+"] = 2
prec["-"] = 2
prec["("] = 1
opStack = Stack()
postfixlist = []
#将语句分割成一个listlit(),解析表达式到单词列表
tokenList = infixexpr.split()
for token in tokenList:
if token in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or token in "0123456789":
postfixlist.append(token)
elif token == "(":
opStack.push(token)
elif token == ")":
topToken = opStack.pop()
while topToken != '(':
postfixlist.append(topToken)
topToken = opStack.pop()
else:
while (not opStack.isEmpty()) and \
(prec[opStack.peek()] >= prec[token]):
postfixlist.append(opStack.pop())
opStack.push(token)
while not opStack.isEmpty():
postfixlist.append(opStack.pop())
return " ".join(postfixlist)
print(infixToPostfix('(V*A)+(B*C)'))
- 总结
总之,栈是一种先进后出的线性数据结构,可用于判断对称问题、反转问题等。常用的pop、push、append等函数实现起来也非常简单。今天的内容基本就是这样,希望能对学习数据结构的你有所帮助。