如何根据前序、中序、后序遍历还原二叉树


在网上看到了一篇 讲的挺好的还原二叉树的博客 分享一下
附上原文链接 : http://blog.youkuaiyun.com/yanerhao/article/details/45175943

首先我们得知道概念:

前序遍历:先访问当前节点,再访问当前节点的左子树,最后访问当前节点的右子树。对于二叉树,深度遍历与此同。规律:根在前;子树在根后且左子树比右子树靠前,且第一个就是根节点;

中序遍历:先访问当前节点的左子树,然后访问当前节点,最后是当前节点的右子树,二叉树,中序遍历会得到数据升序效果。规律:根在中;左子树在跟左边,右子树在根右边,左边部分是根结点的左子树的中序遍历序列,右边部分是根结点的右子树的中序遍历序列 ;

后序遍历:先访问当前节点的左子树,然后是当前节点的又子树,最后是当前节点。规律:根在后;子树在根前且左子树比右子树靠前,且最后一个节点是根节点。

一、前序+中序

  1. 根据前序序列的第一个元素建立根结点;
  2. 在中序序列中找到该元素,确定根结点的左右子树的中序序列;
  3. 在前序序列中确定左右子树的前序序列;
  4. 由左子树的前序序列和中序序列建立左子树;
  5. 由右子树的前序序列和中序序列建立右子树。
    如:已知一棵二叉树的先序遍历序列和中序遍历序列分别是abdgcefh、dgbaechf,求二叉树及后序遍历序列。
    先序:abdgcefh—>a bdg cefh

中序:dgbaechf—->dgb a echf

得出结论:a是树根,a有左子树和右子树,左子树有bdg结点,右子树有cefh结点。
先序:bdg—>b dg

中序:dgb —>dg b

得出结论:b是左子树的根结点,b无右子树,有左子树。
先序:dg—->d g

中序:dg—–>dg

得出结论:d是b左子树的根节点,d无左子树,g是d的右子树

然后对于a 的右子树类似可以推出

最后还原:                                            a

                                      b                                                 c

               d                                                       e                         f

                     g                                                                      h

后序遍历:gdbehfca

二、后序+中序:

已知一棵二叉树的后序序列和中序序列,构造该二叉树的过程如下:
1. 根据后序序列的最后一个元素建立根结点;
2. 在中序序列中找到该元素,确定根结点的左右子树的中序序列;
3. 在后序序列中确定左右子树的后序序列;
4. 由左子树的后序序列和中序序列建立左子树;
5. 由右子树的后序序列和中序序列建立右子树

如还是上面题目:如:已知一棵二叉树的后序遍历序列和中序遍历序列分别是gdbehfca、dgbaechf,求二叉树

后序:gdbehfca—->gdb ehfc a

中序:dgbaechf—–>dgb a echf
得出结论:a是树根,a有左子树和右子树,左子树有bdg结点,右子树有cefh结点。
后序:gdb—->gd b

中序:dgb—–>dg b

得出结论:b是a左子树的根节点,无右子树,有左子树dg。

后序:gd—->g d

中序:dg—–>d g

得出结论:d是b的左子树根节点,g是d的右子树。

然后对于a 的右子树类似可以推出。然后还原。
三、前序+后序

前序和后序在本质上都是将父节点与子结点进行分离,但并没有指明左子树和右子树的能力,因此得到这两个序列只能明确父子关系,而不能确定一个二叉树。 故此法无。不能唯一确定一个二叉树。

题目解析http://blog.youkuaiyun.com/changjiale110/article/details/79109643


原作者链接:
https://blog.youkuaiyun.com/changjiale110/article/details/79489884

### 构建二叉树的方法 #### 使用先和中遍历构建二叉树 对于给定的先和中遍历列,可以通过以下方法构建二叉树: - 对于先遍历,第一个元素总是根节点。找到该元素在中遍历中的位置,则可区分出左子树和右子树[^1]。 ```python def build_tree(preorder, inorder): if not preorder or not inorder: return None root_val = preorder[0] root_index_inorder = inorder.index(root_val) root = TreeNode(root_val) root.left = build_tree( preorder[1:root_index_inorder + 1], inorder[:root_index_inorder] ) root.right = build_tree( preorder[root_index_inorder + 1:], inorder[root_index_inorder + 1:] ) return root ``` 此算法利用了特性A(先遍历的第一个元素是根节点)和特性C(通过中遍历划分左右子树),并递归应用这些原则直到完成整个树的构建。 #### 利用后序与中遍历来创建二叉树 当拥有后序和中遍历时,由于后序遍历最后一个访问的是根节点,因此可以从这里入手进行构建工作: - 后序遍历的最后一项代表当前子树的根节点,在中遍历里定位到这个值的位置之后同样能够分离出左右两部分作为新的子问题求解对象。 ```python def build_tree_from_post_and_in(postorder, inorder): if not postorder or not inorder: return None root_val = postorder[-1] root_index_inorder = inorder.index(root_val) root = TreeNode(root_val) root.left = build_tree_from_post_and_in( postorder[:root_index_inorder], inorder[:root_index_inorder] ) root.right = build_tree_from_post_and_in( postorder[root_index_inorder:-1], inorder[root_index_inorder + 1:] ) return root ``` 这段代码实现了基于特性和递归策略来恢复原始二叉树结构的过程。 #### 结合三者的信息重建更复杂的场景 如果同时给出了三个不同类型的遍历结果——即先、中以及后序遍历列表,理论上讲只需要其中任意两个即可唯一确定一棵二叉树。然而实际操作上通常会选择最方便的一对组合来进行处理,比如上述提到过的先加中或者是后序配中的方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值