栈
后进先出,常见的缓存结构
#栈是保证元素后进先出
'''
ADT Stack:
Stack(self) #创建空栈
is_emplty(self) #判断栈是否为空,空时返回True否则返回False
push(self,elem) #压栈
pop(self) #弹出
top(self) #取得最后压入栈的元素
'''
a)实现
'''
栈的顺序表实现
'''
class StackUnderflow(ValueError): #空栈访问
pass
class SStack(): #基于顺序表技术实现的栈类
def __init__(self): #用list对象_elems存储栈元素
self._elems = [] #所有栈操作都映射到list操作
def is_emply(self):
return self._elems == []
def top(self):
if self._elems == []:
raise StackUnderflow('in SStack.top()')
return self._elems[-1]
def push(self,elem):
self._elems.append(elem)
def pop(self):
if self._elems == []:
raise StackUnderflow('in SStack.top()')
return self._elems.pop()
#定义表节点类
class LNode:
def __init__(self,elem,next_=None):
self.elem=elem
self.next=next_
class LStack(): #基于链表技术实现的栈类,用LNode作为结点
def __init__(self):
self._top = None
def is_empty(self):
return self._top is None
def top(self):
if self._top is None:
raise StackUnderflow('in LStack.top()')
return self._top.elem
def push(self,elem):
self._top = LNode(elem,self._top)
def pop(self):
if self._top is None:
raise StackUnderflow('in LStack.top()')
p = self._top
self._top = p.next
return p.elem
b)简单应用
#括号匹配问题
def check_parens(text):
'''括号配对检查函数,text是被检查的正文串'''
parens = '()[]{}'
open_parens = '([{'
opposite = { ')':'(', ']':'[', '}':'{'}
def parentheses(text):
'''括号生成器,每次调用返回text里的下一括号及其位置'''
i,text_len = 0, len(text)
while True:
while i<text_len and text[i] not in parens:
i+=1
if i>=text_len:
return
yield text[i],i
i+=1
st=SStack() #栈
for pr,i in parentheses(text): #迭代
if pr in open_parens:
st.push(pr) #压栈
elif st.pop()!=opposite[pr]: #匹配失败,推出
print('Unmatching is foundat',i,'for',pr)
return False
print('All parentheses are correctly matched')
c)栈和递归
1、递归函数的运行需要栈(程序运行栈)。后调用先返回
2、任何递归定义的函数(程序),都可以通过引入一个栈保存 中间结果,翻译为一个非递归的过程。与此对应,任何一个包含循环的 程序都可翻译为一个不包含循环的递归程序。(就目前计算机的算力来说,函数调用的效率损失多半都可以接受,所以不一定非得翻译成非递归)