python 105. 从前序与中序遍历序列构造二叉树 106. 从中序与后序遍历序列构造二叉树 108. 根据前序和后序遍历构造二叉树

先序遍历和后序遍历为什么不能唯一地确定一棵树?:
https://blog.csdn.net/GYQJN/article/details/52709912
只有每个节点度为2或者0的时候前序和后序才能唯一确定一颗二叉树,只有一个子节点是无法确定的,因为你无法判断他是左子树还是右子树。
105. 从前序与中序遍历序列构造二叉树
https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
106. 从中序与后序遍历序列构造二叉树
https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
108. 根据前序和后序遍历构造二叉树
https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-postorder-traversal/

从来都是用来当填空题的。现在要求写程序。
比如:

     A
  B     C
F      D  E

a=[‘A’,‘B’,‘F’,‘C’,‘D’,‘E’] #前序样子
b=[‘F’,‘B’,‘A’,‘D’,‘C’,‘E’] #中序样子
c=[‘F’,‘B’,‘D’,‘E’,‘C’,‘A’] #后序样子
规律:
在这里插入图片描述
要点:树的前序遍历第一个是根节点。长度关系。子数递归满足此条件。



from typing import List

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution:
    def buildTreeFromPreorderInorder(self, preorder: List[str], inorder: List[str]) -> TreeNode:

        n = len(preorder)
        # 构造哈希映射,帮助我们快速定位根节点
        index = {element: i for i, element in enumerate(inorder)}


        def helper(preorder_left: int, preorder_right: int, inorder_left: int, inorder_right: int):
            if preorder_left > preorder_right:
                return None

            # 前序遍历中的第一个节点就是根节点
            preorder_root = preorder_left
            # 在中序遍历中定位根节点
            inorder_root = index[preorder[preorder_root]]

            # 先把根节点建立出来
            root = TreeNode(preorder[preorder_root])
            # 得到左子树中的节点数目
            size_left_subtree = inorder_root - inorder_left
            # 递归地构造左子树,并连接到根节点
            # 先序遍历中「从 左边界+1 开始的 size_left_subtree」个元素就对应了中序遍历中「从 左边界 开始到 根节点定位-1」的元素
            root.left = helper(preorder_left + 1, preorder_left + size_left_subtree, inorder_left, inorder_root - 1)
            # 递归地构造右子树,并连接到根节点
            # 先序遍历中「从 左边界+1+左子树节点数目 开始到 右边界」的元素就对应了中序遍历中「从 根节点定位+1 到 右边界」的元素
            root.right = helper(preorder_left + size_left_subtree + 1, preorder_right, inorder_root + 1, inorder_right)

            return root
        return helper(0, n - 1, 0, n - 1)

    def buildTreeFromInorderPostorder(self, inorder , postorder):
        temp=postorder[:]
        def helper(in_left, in_right):
            # 如果这里没有节点构造二叉树了,就结束
            if in_left > in_right:
                return None

            # 选择 post_idx 位置的元素作为当前子树根节点
            val = temp.pop()
            root = TreeNode(val)

            # 根据 root 所在位置分成左右两棵子树
            index = idx_map[val]

            # 构造右子树
            root.right = helper(index + 1, in_right)
            # 构造左子树
            root.left = helper(in_left, index - 1)
            return root

        # 建立(元素,下标)键值对的哈希表
        idx_map = {val: idx for idx, val in enumerate(inorder)}
        return helper(0, len(inorder) - 1)


    def constructFromPreorderPostorder(self, pre, post):
        if not pre:
            return None
        node = TreeNode(pre[0])
        if len(pre) == 1:
            return node
        i = post.index(pre[1])

        node.left = self.constructFromPreorderPostorder(pre[1:i + 2], post[:i + 1])
        node.right = self.constructFromPreorderPostorder(pre[i + 2:], post[i + 1:-1])

        return node



    def preorderTraversal(self, root: TreeNode) -> List[str]:
        def preorder(root: TreeNode):
            if not root:
                return
            res.append(root.val)
            preorder(root.left)
            preorder(root.right)

        res = list()
        preorder(root)
        return res

    def inorderTraversal(self, root: TreeNode) -> List[str]:
        def preorder(root: TreeNode):
            if not root:
                return
            preorder(root.left)
            res.append(root.val)
            preorder(root.right)

        res = list()
        preorder(root)
        return res

    def postorderTraversal(self, root: TreeNode) -> List[int]:
        def postorder(root: TreeNode):
            if not root:
                return
            postorder(root.left)
            postorder(root.right)
            res.append(root.val)
        res = list()
        postorder(root)
        return res

a = ['A', 'B', 'F', 'C', 'D', 'E']  #前序样子
b = ['F', 'B', 'A', 'D', 'C', 'E']  #中序样子
c = ['F', 'B', 'D', 'E', 'C', 'A']  #后序样子

onexianxu=Solution().buildTreeFromInorderPostorder(b,c)
print('先序',Solution().preorderTraversal(onexianxu))


onezhong=Solution().constructFromPreorderPostorder(a, c)
print('中序',Solution().inorderTraversal(onezhong))

onehouxu=Solution().buildTreeFromPreorderInorder(a,b)
print('后序',Solution().postorderTraversal(onehouxu))





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值