2024-09-01
算法刷题
00

先序遍历和后序遍历为什么不能唯一地确定一棵树?:

https://blog.csdn.net/GYQJN/article/details/52709912

只有每个节点度为2或者0的时候前序和后序才能唯一确定一颗二叉树,只有一个子节点是无法确定的,因为你无法判断他是左子树还是右子树。

  1. 从前序与中序遍历序列构造二叉树

https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

  1. 从中序与后序遍历序列构造二叉树

https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

  1. 根据前序和后序遍历构造二叉树

https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-postorder-traversal/

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

比如:

c
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'] #后序样子

规律:

在这里插入图片描述

要点:树的前序遍历第一个是根节点。长度关系。子数递归满足此条件。

python
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))
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:Dong

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!