括号表示法字符串构造二叉树_[二叉树面试算法]-(七) 重构二叉树-相关题型总结(4题)...

  1. 从前序与中序遍历序列构造二叉树_leetcode105
  2. 从中序与后序遍历序列构造二叉树_leetcode106
  3. 根据前序和后序遍历构造二叉树_leetcode889
  4. 二叉树的序列化与反序列化_leetcode297

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

思路:

第一步:
前序遍历的第一个节点,即为根节点。
第二步:
由根节点,可以在中序遍历中,找到左子树对应的长度。
第三步:
根据左子树的长度,
可以在先序序列和中序序列中,找到左子树和右子树对应的先序序列和中序序列。

代码如下:

class 

2.从中序和后序遍历序列构造二叉树

思路分析:

与上题类似,由后序遍历,来确定根节点的值。
然后,从中序遍历中,找到左右子树的长度及对应的序列,
递归构造即可。

代码如下:

class 

3.从前序和后序遍历序列构造二叉树

思路1:根据前序和后序序列及起始位置来构建二叉树。

前序遍历的第一个节点可以确定根节点.
- 前序序列中,根节点的下一个节点,为左子树的根节点。
- 由前序序列中的根节点的值,可以在后序序列中,找到对应的根节点的位置,从而确定左子树的位置。
依次迭代,便可以递归构造出二叉树。 

代码实现:

class 

拓展:

仅仅知道前序遍历和后序遍历的顺序,不能唯一确定一棵二叉树。如下图所示:

3129bccceba941f2727892094222fba3.png

二叉树遍历情况为

二叉树1的前序序列为

上述题解默认的是构造二叉树1的这种情况。由于leetcode中的测试用例是按照构建二叉树的层次遍历结构来验证,构造的结果,所以,上述代码能够通过。

思路二:leetcode官方题解,易于理解

前序遍历为:
(根结点) (前序遍历左分支) (前序遍历右分支)
而后序遍历为:
(后序遍历左分支) (后序遍历右分支) (根结点)

例如,如果最终的二叉树可以被序列化的表述为 [1, 2, 3, 4, 5, 6, 7],
那么其前序遍历为 [1] + [2, 4, 5] + [3, 6, 7],而后序遍历为 [4, 5, 2] + [6, 7, 3] + [1].

果我们知道左分支有多少个结点,我们就可以对这些数组进行分组,并用递归生成树的每个分支。

算法
我们令左分支有 L 个节点。我们知道左分支的头节点为 pre[1],但它也出现在左分支的后序表示的最后。
所以 pre[1] = post[L-1](因为结点的值具有唯一性),因此 L = post.indexOf(pre[1]) + 1。
现在在我们的递归步骤中,左分支由 pre[1 : L+1] 和 post[0 : L] 重新分支,
而右分支将由 pre[L+1 : N] 和 post[L : N-1] 重新分支。

这里,巧妙的利用数学中的设未知数,设有L个节点,使得编程变得简单。是上述思路一种的简化版。

代码实现如下:

class 

4.二叉树的序列化和反序列化

思路:

序列化,就是层次遍历二叉树,将遍历结果用字符串来表示。若某一节点为null,则用特殊的字符来表示,如“#”
反序列化,根据层次化遍历序列,来重构二叉树。

代码实现:

public 

结语

以上,便是关于二叉树与二叉树结构之间的四类题目总结。

从上面可知,有序列化的某一排序序列,可以反序列化,重构实际的二叉树。因为在序列化的过程中,是用了特殊的字符,来记录null节点的信息。

如果没有用特殊的符号来记录空信息,则需要通过两种方式的遍历序列,才能重构二叉树。

前序遍历+中序遍历,可以唯一确定一棵二叉树。

后序遍历+中序遍历,也可以唯一确定一棵二叉树。

但是,前序遍历+后序遍历,不能唯一确定一棵二叉树。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值