zoukankan      html  css  js  c++  java
  • 07_05.通过链接实现二叉树及其遍历

    from queue.queue import SQueue
    from sstack.stack import SStack
    
    
    class BinTNode:
        def __init__(self, data, left=None, right=None):
            self.data = data
            self.left = left
            self.right = right
    
    
    def count_BinTNodes(t):
        """统计树中结点个数"""
        if t is None:
            return 0
        else:
            return 1 + count_BinTNodes(t.left) + count_BinTNodes(t.right)
    
    
    def sum_BinTNodes(t):
        """所有数值和(二叉树保存的是数值)"""
        if t is None:
            return 0
        else:
            return t.data + sum_BinTNodes(t.left) + sum_BinTNodes(t.right)

    遍历:

    先根序遍历递归:

    def preorder(t, proc):
        """先根序遍历"""
        if t is None:
            return
        assert (isinstance(t, BinTNode))
        proc(t.data)
        preorder(t.left, proc)
        preorder(t.right, proc)
    
    
    tree = BinTNode(1, BinTNode(2, BinTNode(4), BinTNode(5)), BinTNode(3, BinTNode(6), BinTNode(7)))
    preorder(tree, lambda x: print(x, end=' '))  # 1 2 4 5 3 6 7
    print()
    
    
    def print_BinTNodes(t):
        """先根序遍历打印"""
        if t is None:
            print("^", end="")
            return
        print("(" + str(t.data), end="")
        print_BinTNodes(t.left)
        print_BinTNodes(t.right)
        print(")", end="")
    
    
    t = BinTNode(1, BinTNode(2, BinTNode(4), BinTNode(5)), BinTNode(3, BinTNode(6), BinTNode(7)))
    print_BinTNodes(t)  # (1(2(4^^)(5^^))(3(6^^)(7^^)))
    print()

    先根序遍历非递归:

    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()  # 遇到空树回溯
    
    
    tree = BinTNode(1, BinTNode(2, BinTNode(4), BinTNode(5)), BinTNode(3, BinTNode(6), BinTNode(7)))
    preorder_nonrec(tree, lambda x: print(x, end=' '))  # 1 2 4 5 3 6 7
    print("")

    先根序遍历非递归优化:

    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()  # 遇到空树回溯
    
    
    tree = BinTNode(1, BinTNode(2, BinTNode(4), BinTNode(5)), BinTNode(3, BinTNode(6), BinTNode(7)))
    for i in preorder_elements(tree):
        print(i, end=' ')  # 1 2 4 5 3 6 7

    宽度优先遍历:

    def levelorder(t, proc):
        """宽度优先遍历"""
        qu = SQueue()
        qu.enqueue(t)
        while not qu.is_empty():
            n = qu.dequeue()
            if n is None:  # 弹出的树为空则直接跳过
                continue
            qu.enqueue(n.left)
            qu.enqueue(n.right)
            proc(n.data)
    
    
    tree = BinTNode(1, BinTNode(2, BinTNode(4), BinTNode(5)), BinTNode(3, BinTNode(6), BinTNode(7)))
    levelorder(tree, lambda x: print(x, end=' '))  # 1 2 3 4 5 6 7
    print("")

    非递归实现后根序遍历:

    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
    
    
    tree = BinTNode(1, BinTNode(2, BinTNode(4), BinTNode(5)), BinTNode(3, BinTNode(6), BinTNode(7)))
    postorder_nonrec(tree, lambda x: print(x, end=' '))  # 4 5 2 6 7 3 1
    print()

     将二叉树封装成类:

    """二叉树类"""
    from sstack.stack import SStack
    
    
    class BinTNode:
        """结点"""
        def __init__(self, data, left=None, right=None):
            self.data = data
            self.left = left
            self.right = right
    
    
    class BinTree:
        """二叉树"""
        def __init__(self):
            self._root = None
    
        def is_empty(self):
            return self._root is None
    
        def root(self):
            return self._root
    
        def leftchild(self):
            return self._root.left
    
        def rightchild(self):
            return self._root.right
    
        def set_root(self, rootnode):
            self._root = rootnode
    
        def set_left(self, leftchild):
            self._root.left = leftchild
    
        def set_right(self, rightchild):
            self._root.right = rightchild
    
        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.data
                    t = t.left
                t = s.pop()
    
    
    l = BinTNode(2, BinTNode(4), BinTNode(5))
    r = BinTNode(3, BinTNode(6), BinTNode(7))
    tree = BinTree()
    tree.set_root(BinTNode(1))
    tree.set_left(l)
    tree.set_right(r)
    for i in tree.preorder_elements():
        print(i, end=' ')  # 1 2 4 5 3 6 7
    print()
  • 相关阅读:
    Pytorch 四种边界填充方式(Padding)
    数据预处理 —— padding数据
    Python PIL彩色图像转灰度图像
    Python PIL读取与保存图片
    Python-OpenCV 彩色图像转灰度图像
    Python-OpenCV读取与保存图片
    Python 矩阵旋转180度
    Pytorch 扩展Tensor维度、压缩Tensor维度
    基于SSM的健身房管理系统
    大学生创新创业项目-智取乐食
  • 原文地址:https://www.cnblogs.com/fly-book/p/11812311.html
Copyright © 2011-2022 走看看