def check_parens(text): parens = "()[]{}" # 括号字符 open_parens = "([{" # 开括号字符 opposite = {')' : '(', ']' : '[', '}' : '{'} # 表示匹配关系的字典 def parantheses(text): # 括号生成器,每次调用返回text里的下一括号及其位置 i, text_len = 0, len(text) while True: # 从位置0开始扫描字符串,如果不是括号的符号就继续向后扫描 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 parantheses(text): # 对text里的各括号和位置迭代 if pr in open_parens: # 从括号生成器中拿出来的括号符号是开括号,压进栈并继续 st.push(pr) # 不是开括号就是闭括号,这时弹出栈里面的括号,看是否和当前括号匹配 elif st.pop() != opposite[pr]: print('Unmatching is found at', i, 'for', pr) return False # else: # 成功的匹配,啥也不做,继续 print('All parentheses are correctly matched.') return True
def pre_order_nr(tree, func): s = SStack() while tree or not s.is_empty(): while tree: func(tree.root) s.push(tree.right) tree = tree.left tree = s.pop()
def postorder_nonrec(t, proc): s = SStack() while t is not None or not s.is_empty(): while t is not None: #下行循环,直到栈顶的两子树空 s.push(t) t = t.left if t.left is not None else t.right #能左就左否则向右 t = s.pop() #栈顶是应访问节点 proc(t.data) if not s.is_empty() and s.top().left == t: t = s.top().right #栈不空且当前节点是栈定左子节点 else: #没有右子树或右子树遍历完毕,强迫退栈 t = None
def postorder_nonrec(t_, proc): s = SStack() while t_ is not None or not s.is_empty(): while t_ is not None: # 下行循环,直到栈顶的两个树空 s.push(t_) t_ = t_.left if t_.left is not None else t_.right # 注意这个条件表达式的意义:能左就左,否则向右一步 t_ = s.pop() # 栈顶是访问结点 proc(t_.dat) if not s.is_empty() and s.top().left == t_: t_ = s.top().right # 栈不空且当前结点是栈顶的左子结点 else: t_ = None # 没有右子树或右子树遍历完毕,强迫退栈
def trans_infix_suffix(line): st = SStack() exp = [] # 记录转换得到的后缀表达式,采用项表的形式 for x in token(line): if x not in infix_operatios: pass
def preorder_elements(self): t, s = self._root, SStack() while t is not None or not s.is_empty(): while t is not None: s.push(t.right) yield t.dat t = t.left t = s.pop()
def DFS_graph(graph, v0): vnum = graph.vertex_num() visited = [0] * vnum visited[v0] = 1 DFS_seq = [v0] st = SStack() st.push((0, graph.out_edges(v0))) while not st.is_empty(): i, edges = st.pop() if i < len(edges): v, e = edges[i] st.push((i+1, edges)) if not visited[v]: DFS_seq.append(v) visited[v] = 1 st.push((0, graph.out_edges(v))) return DFS_seq
def DFS_graph_non_recursive(graph, v0): # 借用辅助栈 非递归实现 ver_num = graph.get_ver_num() visited = [0] * ver_num visited[v0] = 1 dfs_seq = [v0] #dfs序列 st = SStack() st.push((0, graph.get_outedges(v0))) while not st.is_empty(): i, edges = st.pop() if i < len(edges): v, w = edges[i] st.push((i + 1, edges)) #回溯时访问i+1 if not visited[v]: #v未被访问,记录并继续dfs dfs_seq.append(v) visited[v] = 1 st.push((0, graph.get_outedges(v))) return dfs_seq
def values(self): t, s = self._root, SStack() while t or not s.is_empty(): while t: s.push(t) t = t.left t = s.pop() yield t.data.key, t.data.value t = t.right
def entries(self): t, s = self._root, SStack() while t is not None or not s.is_empty(): while t is not None: s.push(t) t = t.left t = s.pop() yield t.dat.key, t.dat.value t = t.right
def dfs_non_recursive_traverse_postorder(t, proc): #dfs非递归 后根序 s = SStack() while t is not None or not s.is_empty(): while t is not None: s.push(t) if t.left is not None: t = t.left else: t = t.right t = s.pop() proc(t.data) if not s.is_empty() and s.top().left == t: t = s.top().right #这一步很关键 else: t = None
def DFS_SpanTree(graph, v0): vertex_num = graph.get_ver_num() dfs_spantree = [] visited = [0] * vertex_num visited[v0] = 1 st = SStack() st.push((0, v0, graph.get_outedges(v0))) while not st.is_empty(): i, prev_v, edges = st.pop() if i < len(edges): v, w = edges[i] st.push((i + 1, prev_v, edges)) if not visited[v]: visited[v] = 1 st.push((0, v, graph.get_outedges(v))) dfs_spantree.append((prev_v, w, v)) return dfs_spantree
def preorder_elements(t_): s = SStack() while t_ is not None or not s.is_empty(): while t_ is not None: s.push(t_.right) yield t_.dat t_ = t_.left t_ = s.pop()
def preorder_nonrec(t, proc): s = SStack() while t is not None or not s.is_empty(): while t is not None: proc(t.data) s.push(t.right) t = t.left t = s.pop()
def preorder_elements(t): s = SStack() while t is not None or not s.is_empty(): while t is not None: s.push(t.right) yield t.data t = t.left t = s.pop()
def dfs(graph, s): stack = SStack() stack.push(s) seen = set() seen.add(s) parent = {s: None} while not stack.is_empty(): vertex = stack.pop() nodes = graph[vertex] for i in nodes: if i not in seen: stack.push(i) seen.add(i) parent[i] = vertex print vertex return parent
def norec_fact(n): # 自己管理栈,模拟函数调用过程 res = 1 st = SStack() while n > 0: st.push(n) n -= 1 while not st.is_empty(): res *= st.pop() return res
def dfs_non_recursive_traverse(t, proc): #dfs非递归 先根序 s = SStack() while t is not None or not s.is_empty(): while t is not None: proc(t.data) s.push(t.right) t = t.left t = s.pop()
def preorder_nonrec(t_, proc): """ 时间复杂性: O(n) 空间复杂性: O(log(n)) """ s = SStack() while t_ is not None or not s.is_empty(): while t_ is not None: proc(t_.dat) s.push(t_.right) t_ = t_.left t_ = s.pop()
def maze_solver(maze, start, end): if start == end: print(start) return st == SStack() mark(maze, start) st.push((start, 0)) while not st.is_empty(): pos, nxt = st.pop() for i in range(nxt, 4): nextp = pos[0] + dirs[i][0], pos[1] + dirs[i][1] if nextp == end: print_path(end, pos, st) return if passable(maze, nextp): st.push((pos, i + 1)) mark(maze, nextp) st.push((nextp, 0)) break print("No path found.")
def delete(self, key): p, q = self._root, None parent_nodes = SStack() #记录所有父结点 #检索 并记录路径 while p is not None and key != p.data.key: q = p if key < p.data.key: p = p.left parent_nodes.push(q) else: p = p.right parent_nodes.push(q) #没有找到删除结点 if key != p.data.key: return assoc = p #删除叶结点 if p.right == None and p.left == None: DictAVL.del_adjustment_leaf(self._root, p, q, parent_nodes) return assoc # 只有左子树 if p.left is not None and p.right is None: DictAVL.del_adjustment_ol(p, q, parent_nodes) return assoc # 只有右子树 if p.left is None and p.right is not None: DictAVL.del_adjustment_or(p, q, parent_nodes) return assoc #左右子树都有 if p.left is not None and p.right is not None: p_traverse, q_traverse = p, None if p.bf == -1: #若右子树高 #找到右子树的最左结点 一定是一个叶结点 while p_traverse is not None: q_traverse = p_traverse #q_traverse是p_traverse的父结点 p_traverse = p_traverse.right parent_nodes.push(p_traverse) p.data.key, p.data.value = p_traverse.data.key, p_traverse.data.value #进行交换 DictAVL.del_adjustment_leaf(self._root, p_traverse, q_traverse, parent_nodes) #进行调整 return assoc elif p.bf == 0: #两棵子树一样高 左子树最右 右子树最左都可以 #找到右子树的最左结点 一定是一个叶结点 while p_traverse is not None: q_traverse = p_traverse #q_traverse是p_traverse的父结点 p_traverse = p_traverse.right parent_nodes.push(p_traverse) p.data.key, p.data.value = p_traverse.data.key, p_traverse.data.value #进行交换 DictAVL.del_adjustment_leaf(self._root, p, q, parent_nodes) return assoc else: #p.bf == 1 while p_traverse is not None: q_traverse = p_traverse #q_traverse是p_traverse的父结点 p_traverse = p_traverse.left parent_nodes.push(p_traverse) p.data.key, p.data.value = p_traverse.data.key, p_traverse.data.value #进行交换 DictAVL.del_adjustment_leaf(self._root, p, q, parent_nodes) return assoc
def trans_infix_suffix(line): st = SStack() exp = [] for x in tokens(line): # tokens是一个待定义的生成器 if x not in infix_operators: # 运算对象直接送出 exp.append(x) elif st.is_empty() or x == '(': # 左括号进栈 st.push(x) elif x == ')': # 处理右括号的分支 while not st.is_empty() and st.top() != '(': exp.append(st.pop()) if st.is_empty(): # 没有找到左括号,就是不配对 raise SyntaxError('Missing "(".') st.pop() # 弹出左括号,右括号也不进栈 else: # 处理运算符,运算符都看作左结合 while (not st.is_empty()) and priority[st.top()] >= priority[x]: exp.append(st.pop()) st.push(x) # 算数运算符进栈 while not st.is_empty(): # 送出栈里剩下的运算符 if st.pop() == '(': # 如果还有左括号,就是不配对 raise SyntaxError('Extra "(".') exp.append(st.pop()) return exp
def check_parens(text): """ 括号匹配检查函数,text是被检查的正文串 """ parens = '()[]{}' open_parens = '([{' opposite = {')': '(', ']': '[', '}': '{'} # 表示配对关系的字典 st = SStack() # 保存括号的栈 st_i = SStack() for pr, i in parentheses(text, parens): # 对text里各括号和位置迭代 if pr in open_parens: # 开括号,压进栈并继续 st.push(pr) st_i.push(i) elif st.is_empty() or st.pop() != opposite[pr]: # 不匹配就是失败,退出 if not st.is_empty(): st_i.pop() print('Unmatching is found at', i, 'for', pr) return False else: # 这是一次括号配对成功,什么也不做,继续 st_i.pop() if not st.is_empty(): ''' st_i_ = '' st_ = '' while not st.is_empty(): st_i_ = str(st_i.pop()) + st_i_ st_ = st.pop() + st_ print('Unmatching is found at', st_i_, 'for', st_) ''' print('Unmatching is found at', st_i.pop(), 'for', st.pop()) return False print('All parentheses are correctly matched.') return True
def maze_solver(maze, start, end): if start == end: print(start) return st = SStack() mark(maze, start) st.push((start, 0)) # 入口和方向0的序对入栈 while not st.is_empty(): # 走不通时回退 pos, nxt = st.pop() # 取栈顶及其探查方向 for i in range(nxt, 4): # 依次检查未探查方向 nextp = (pos[0] + dirs[i][0], pos[1] + dirs[i][1]) # 算出下一位置 if nextp == end: # 到达出口打印路径 print(end, end=' ') print(pos, end=' ') while not st.is_empty(): print(st.pop()[0], end=' ') return if passable(maze, nextp): # 遇到未探查的新位置 st.push((pos, i + 1)) # 原位置和下一方向入栈 mark(maze, nextp) st.push((nextp, 0)) # 新位置入栈 break # 退出内层循环,下次迭代将以新栈顶为当前位置继续 print('No path found.') # 找不到路径