编程基础,二叉树专场 (python版)

# -*- coding:utf-8 -*-
preorder_list = []
inorder_list = []
deorder_list = []
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.lchild = None
        self.rchild = None

class BinaryTree:
    def __init__(self):
        self.root = None
        self.index = -1

    def addElem(self,x):
        tree_node = TreeNode(x)
        if self.root is None:
            self.root = tree_node
            return
        else:
            quque = [self.root]
            while quque:
                elem = quque.pop(0)
                if elem.lchild is None:
                    elem.lchild = tree_node
                    return
                else:
                    quque.append(elem.lchild)
                if elem.rchild is None:
                    elem.rchild = tree_node
                    return
                else:
                    quque.append(elem.rchild)
    # 二叉树层次遍历
    def hirachicalOrder(self, root):
        if root is None:
            return None
        else:
            quque = [root]
            while quque:
                elem = quque.pop(0)
                print(elem.val,end=' ')
                if elem.lchild is not None:
                    quque.append(elem.lchild)
                if elem.rchild is not None:
                    quque.append(elem.rchild)
    # 二叉树前序遍历
    def preOrder(self, root):
        if root is None:
            return
        global preorder_list
        preorder_list.append(root.val)
        self.preOrder(root.lchild)
        self.preOrder(root.rchild)

    # 二叉树中序遍历
    def inOrder(self, root):
        if root is None:
            return
        self.inOrder(root.lchild)
        global inorder_list
        inorder_list.append(root.val)
        self.inOrder(root.rchild)

    # 二叉树后序遍历
    def deOrder(self, root):
        if root is None:
            return
        self.deOrder(root.lchild)
        self.deOrder(root.rchild)
        global deorder_list
        deorder_list.append(root.val)

    # 根据前序遍历和中序遍历结果重建二叉树
    def reConstructBinaryTree1(self, preorder, inorder):
        if len(preorder) == 0:
            return None
        elif len(preorder) == 1:
            pRoot = TreeNode(preorder[0])
            return pRoot
        else:
            pRoot = TreeNode(preorder[0])
            index = inorder.index(preorder[0])
            pRoot.lchild = self.reConstructBinaryTree1(preorder[1:index+1], inorder[:index])
            pRoot.rchild = self.reConstructBinaryTree1(preorder[index+1:], inorder[index+1:])
            return pRoot

    # 根据后序遍历和中序遍历结果重建二叉树
    def reConstructBinaryTree2(self, deorder, inorder):
        if len(deorder) == 0:
            return None
        elif len(deorder) == 1:
            pRoot = TreeNode(deorder[0])
            return pRoot
        else:
            pRoot = TreeNode(deorder[-1])
            index = inorder.index(deorder[-1])
            pRoot.lchild = self.reConstructBinaryTree2(deorder[:index],inorder[:index])
            pRoot.rchild = self.reConstructBinaryTree2(deorder[index:-1],inorder[index+1:])
            return pRoot

    # 二叉树镜像
    def Mirror(self,root):
        if root is None:
            return None
        else:
            root.lchild, root.rchild = root.rchild, root.lchild
            self.Mirror(root.lchild)
            self.Mirror(root.rchild)

    # 和为定值的某一路径
    def FindPath(self, root, expectNumber):
        if root is None:
            return []
        if root.lchild is None and root.rchild is None:
            # 到达根节点时刚好找到符合要求的数字
            if root.val == expectNumber:
                return [[root.val]]
            else:
                return []
        # 可能同时存在多条路径
        item = self.FindPath(root.lchild, expectNumber-root.val) + self.FindPath(root.rchild, expectNumber-root.val)
        return [[root.val] + val for val in item]

    # 二叉树的深度
    def TreeDepth(self, pRoot):
        if pRoot is None:
            return 0
        left_tree_depth = self.TreeDepth(pRoot.lchild) + 1
        right_tree_depth = self.TreeDepth(pRoot.rchild) + 1
        return max(left_tree_depth, right_tree_depth)

    # 平衡二叉树判断,左右子树深度差值不大于1
    def IsBalanced_Solution(self, pRoot):
        if pRoot is None:
            return True
        if abs(self.TreeDepth(pRoot.lchild) - self.TreeDepth(pRoot.rchild)) > 1:
            return False
        return self.IsBalanced_Solution(pRoot.lchild) and self.IsBalanced_Solution(pRoot.rchild)

    # 对称二叉树判断
    def isSymmetrical(self, pRoot):
        return self.isSameTree(pRoot.lchild, pRoot.rchild)

    def isSameTree(self, pRoot_l, pRoot_r):
        if pRoot_l is None and pRoot_r is None:
            return True
        if pRoot_l is None or pRoot_r is None:
            return False
        if pRoot_l.val != pRoot_r.val:
            return False
        return self.isSameTree(pRoot_l.lchild,pRoot_r.rchild) and  self.isSameTree(pRoot_l.rchild,pRoot_r.lchild)

    # z字形打印二叉树
    def zPrint(self, pRoot):
        if pRoot is None:
            return []
        queue = [pRoot]
        change_direction = False
        tree_list = []
        while queue:
            current = []
            new_list = []
            for item in queue:
                current.append(item.val)
                if item.lchild:
                    new_list.append(item.lchild)
                if item.rchild:
                    new_list.append(item.rchild)
            tree_list += current[::-1] if change_direction else current
            change_direction = not change_direction
            queue = new_list
        return tree_list

    # 二叉树序列化
    def Serialize(self, pRoot):
        if pRoot is None:
            return '#!'
        return str(pRoot.val) + '!' + self.Serialize(pRoot.lchild) + self.Serialize(pRoot.rchild)

    # 二叉树反序列化
    def Deserialize(self, tree_node_list):
        # 每调用一次该递归函数,相当于游标右移一位
        self.index += 1
        if self.index >= len(tree_node_list):
            return None
        pRoot = None
        if (tree_node_list[self.index] != '#'):
            pRoot = TreeNode(tree_node_list[self.index])
            pRoot.lchild = self.Deserialize(tree_node_list)
            pRoot.rchild = self.Deserialize(tree_node_list)
        return pRoot

    # 树的子结构
    def HasSubtree(self, pRoot1, pRoot2):
        if pRoot1 is None or pRoot2 is None:
            return False
        return self.isSubtree(pRoot1, pRoot2) or self.HasSubtree(pRoot1.lchild, pRoot2) or self.HasSubtree(pRoot1.rchild, pRoot2)

    def isSubtree(self, pRoot1, pRoot2):
        if pRoot2 is None:
            return True
        if pRoot1 is None:
            return False
        if pRoot1.val != pRoot2.val:
            return False
        return self.isSubtree(pRoot1.lchild, pRoot2.lchild) and self.isSubtree(pRoot1.rchild, pRoot2.lchild)

if __name__ == '__main__':
    tree = BinaryTree()
    tree.addElem(1)
    tree.addElem(5)
    tree.addElem(3)
    tree.addElem(9)
    tree.addElem(2)
    tree.addElem(6)
    tree.addElem(7)
    tree.addElem(0)

    # 前序中序后续遍历结果
    tree.preOrder(tree.root)
    tree.inOrder(tree.root)
    tree.deOrder(tree.root)
    print('preorder',preorder_list)
    print('inorder',inorder_list)
    print('deorder',deorder_list)

    # 重建二叉树
    tree.hirachicalOrder(tree.reConstructBinaryTree1(preorder_list,inorder_list))
    print('')
    tree.hirachicalOrder(tree.reConstructBinaryTree2(deorder_list,inorder_list))
    print('')

    # 二叉树镜像
    tree.Mirror(tree.root)
    tree.hirachicalOrder(tree.root)
    print('')

    # 和为定值的某一路径
    print('expect num 15, path : ',tree.FindPath(tree.root,15))

    # 二叉树的深度
    depth = tree.TreeDepth(tree.root)
    print('depth of the tree is : %d'%depth)

    # 平衡二叉树判断
    print(tree.IsBalanced_Solution(tree.root))

    # 对称二叉树判断
    print(tree.isSymmetrical(tree.root))

    # z字形打印二叉树
    print(tree.zPrint(tree.root))

    # 序列化二叉树
    pickling = tree.Serialize(tree.root)
    print(pickling)

    # 反序列化二叉树
    pRoot = tree.Deserialize(pickling.split('!'))
    tree.hirachicalOrder(pRoot)

猜你喜欢

转载自blog.csdn.net/eucommiaulmoides/article/details/80584238