Python数据结构与算法—栈
栈
1.定义:栈是限制在一端进行插入操作和删除操作的线性表(俗称堆栈),允许进行操作的一端称为“栈顶”,另一固定端称为“栈底”,当栈中没有元素时称为“空栈”。
2.特点:
- 栈只能在一端进行数据操作
- 栈模型具有后进先出或者叫做后进先出的规律
3.栈的代码实现
栈的操作有入栈(压栈),出栈(弹栈),判断栈的空满等操作。
1 """ 2 栈模型顺序存储 3 重点代码 4 5 思路分析: 6 1. 列表即顺序存储,但是功能太多,不符合栈模型 7 2. 利用列表,封装类,提供栈的接口方法 8 """ 9 10 # 自定义异常类 11 class StackError(Exception): 12 pass 13 14 # 顺序栈类封装 15 class SStack: 16 def __init__(self): 17 # 属性为空列表,这个列表就是栈的存储空间 18 # 列表最后一个元素为栈顶元素 19 self._elems = [] 20 21 # 判断栈是否为空 22 def is_empty(self): 23 return self._elems == [] 24 25 # 入栈 elem 26 def push(self,elem): 27 self._elems.append(elem) 28 29 # 出栈 30 def pop(self): 31 # self._elems为空则if语句为真 32 if not self._elems: 33 raise StackError("stack is empty") 34 return self._elems.pop() # 弹出列表最后一个 35 36 # 查看栈顶元素 37 def top(self): 38 if not self._elems: 39 raise StackError("stack is empty") 40 return self._elems[-1] 41 42 if __name__ == "__main__": 43 st = SStack() # 初始化栈 44 st.push(10) 45 st.push(20) 46 st.push(30) 47 while not st.is_empty(): 48 print(st.pop())
1 """ 2 栈的链式存储 3 重点代码 4 5 思路分析: 6 1. 基本的实现模型源于 链表 7 2. 栈顶位置? 栈顶相当于链表的尾部 8 """ 9 10 11 class StackError(Exception): 12 pass 13 14 15 # 节点类 16 class Node(): 17 def __init__(self, data, next=None): 18 self.data = data 19 self.next = next 20 21 22 # 栈类 23 class LStack(): 24 def __init__(self): 25 # 尾部为None 26 self.top_ = None 27 28 # 是否为空栈 29 def empty(self): 30 if self.top_ is None: 31 print("空栈") 32 else: 33 print("不是空栈") 34 35 # 入栈 36 def push(self, data): 37 # 同链表p=p.next 38 self.top_ = Node(data, self.top_) 39 40 # 弹栈 41 def pop(self): 42 # 如果是空栈 人工报错 43 if self.top_ is None: 44 raise StackError("stack is empty") 45 # 出栈的值为栈顶的值 46 data = self.top_.data 47 # 栈顶的位置向下移 48 self.top_ = self.top_.next 49 return data 50 51 # 查看栈顶的值 52 def get_top(self): 53 if self.top_ is None: 54 raise StackError("stack is empty") 55 # 不是空栈的话,self.top_.data便是栈顶的值 56 return self.top_.data 57 58 59 print("--------------测试-------------------") 60 if __name__ == '__main__': 61 ls = LStack() 62 ls.empty() # 空栈 63 ls.push(10) 64 ls.push(100) 65 ls.push(200) 66 print(ls.get_top()) # 200 67 ls.pop() 68 ls.pop() 69 print(ls.get_top()) # 10 70 ls.empty() # 不是空栈
练习:一段文字,可能存在括号配对错误的情况。就是少一个或者括号不一致
要求写一段代码,检测这段文字有没有括号书写异常
括号包含{},[],()
1 import 栈顺序存储模型(SStack) 2 3 st = SStack() 4 parens = "{}()[]" # 需要验证的字符 5 left_parens = "{([" 6 # 验证配对是否正确 7 opposite_dict = {'}': '{', 8 ']': '[', 9 ')': '('} 10 11 12 # 负责提供遍历 13 def for_text(text): 14 """ 15 遍历字符串,提供括号字符和其位置 16 :param str: 17 :return: 括号字符的列表和位置 18 """ 19 # i是字符串的索引,text_len是长度 20 i, text_len = 0, len(text) 21 while True: 22 # 循环遍历字符串 23 # 到结尾结束,遇到括号提供给ver 24 # 如果长度大于字符串的索引 并且遍历得到的字符串不在parens里停止循环 25 while i < text_len and text[i] not in parens: 26 i += 1 27 if i >= text_len: 28 return 29 else: 30 yield text[i], i 31 i += 1 32 33 34 # 字符是否匹配的验证工作 35 def ver(): 36 for pr, i in for_text(text): 37 if pr in left_parens: 38 st.push_stack((pr, i)) # 左括号入栈 39 elif st.is_empty_stack() or st.pop_stack()[0] != opposite_dict[pr]: 40 # 栈里是空值或者栈里抛出的括号不在字典对应的值中 41 print("没匹配%d的位置%s" % (i, pr)) 42 # for 循环正常结束 43 break 44 else: 45 if st.is_empty_stack(): 46 print("成了") 47 else: 48 p = st.pop_stack() 49 print("没匹配%d的位置%s" % (p[1], p[0])) 50 51 52 text = "dsfadsfa{d(sfa)dfa[dsf]}asdf" 53 # for pr, i in for_text(text): 54 # print(pr, i) 55 56 ver()