Esempio n. 1
0
 def preorer_elements(self):
     """先序遍历生成器"""
     tree, stk = self._root, SStack()
     while tree is not None or not stk.is_empty():
         while tree is not None:
             stk.push(tree.right)
             yield tree.data
             tree = tree.left
         tree = stk.pop()
Esempio n. 2
0
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)))
Esempio n. 3
0
    def entries(self):
        """返回关键码、值对的生成器"""

        tree, stk = self._root, SStack()
        while tree is not None or not stk.is_empty():
            while tree is not None:
                stk.push(tree)
                tree = tree.left
            tree = stk.pop()
            # 不直接返回tree.data(Assoc类对象),保证关键码的不可变
            yield tree.data.key, tree.data.value
            tree = tree.right
Esempio n. 4
0
    def values(self):
        """生成字典所有值序列的迭代器
        中序遍历实现"""

        tree, stk = self._root, SStack()
        while tree is not None or not stk.is_empty():
            while tree is not None:
                stk.push(tree)
                tree = tree.left
            tree = stk.pop()
            yield tree.data.value
            tree = tree.right
Esempio n. 5
0
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  # 没有右子树或右子树遍历完毕,强迫退栈
Esempio n. 6
0
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()  # 左子树处理完,处理栈中的右子树
Esempio n. 7
0
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()  # 左子树处理完,处理栈中的右子树
Esempio n. 8
0
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  # 处理右子树
Esempio n. 9
0
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.")