def inorder_nonrec(tree, proc): """非递归中序遍历""" stk = SStack() while tree is not None or not stk.is_empty(): while tree: stk.push(tree) # 不断压入左子树,root在栈底 tree = tree.left tree = stk.pop() proc(tree.data) tree = tree.right # 处理右子树
def preorder_elements(tree): """非递归先序遍历得到一个二叉树迭代器""" stk = SStack() while tree or not stk.is_empty(): while tree: if tree.right is not None: # 空的右子树不入栈,节省栈空间 stk.push(tree.right) # 右子树入栈 yield tree.data tree = tree.left # 处理左子树 if not stk.is_empty(): tree = stk.pop() # 左子树处理完,处理栈中的右子树
def preorder_nonrec(tree, proc): """非递归先序遍历 用栈缓存---先进后出---先将右子树压入栈""" stk = SStack() while tree or not stk.is_empty(): while tree: if tree.right is not None: # 空的右子树不入栈,节省栈空间 stk.push(tree.right) # 右子树入栈 proc(tree.data) tree = tree.left # 处理左子树 if not stk.is_empty(): tree = stk.pop() # 左子树处理完,处理栈中的右子树
def postorder_nonrec(tree, proc): """非递归后序遍历 1--内曾循环找当前子树的最下最左结点,将其入栈后终止 2--如果被访问结点是其父的左子结点,直接转到其右兄弟结点继续 3--如被处理结点是其父的右子结点,设tree为None将迫使外层循环的下次迭代弹出并访问更上一层的结点 """ stk = SStack() while tree or not stk.is_empty(): while tree: # 下行循环,直到栈顶的两子树空 stk.push(tree) # 有左子树就取左入栈,因为有子树要先出栈 tree = tree.left if tree.left else tree.right tree = stk.pop() # 访问栈顶 proc(tree.data) if not stk.is_empty() and stk.top().left == tree: # 栈不空且当前结点是栈顶的左子节点 tree = stk.top().right else: tree = None # 没有右子树或右子树遍历完毕,强迫退栈
def DFS_graph(graph, v0): """从graph的v0顶点深有优先非递归得到的DFS序列""" vnum = graph.vertex_num() visited = [0] * vnum # 记录已访问顶点 visited[v0] = 1 DFS_seq = [v0] # 记录遍历序列 stk = SStack() stk.push((0, graph.out_edges(v0))) # 入栈(i, edges) yield v0 while not stk.is_empty(): # 下次应访问edges[i] i, edges = stk.pop() if i < len(edges): v, _ = edges[i] stk.push((i + 1, edges)) # 下次回来将访问edges[i+1] if not visited[v]: # v未访问,访问并记录可达顶点 DFS_seq.append(v) yield v # 返回生成器 visited[v] = 1 stk.push((0, graph.out_edges(v)))
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_path(end, pos, st) print(end, 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.")