算法通关村第六关—如何使用中序和后序来恢复一颗二叉树

1. 树的常见概念

1.1 树

树是一个有n个有限节点组成一个具有层次关系的集合,每个节点有0个或者多个子节点,没有父节点的节点称为根节点,也就是说除了根节点以外每个节点都有父节点,并且有且只有一个。

比如下面这张图:

1.png

请理清一下上面这张图的人物关系:

上面这张图只有一个根节点,祖父作为根可以叫做大根堆,而你作为根只能叫做小根堆。向下发散出不同的结点,一个结点下面连着几个线叫做,而下面没有了结点就称为叶子

同一层的叫兄弟结点,下一层的叫孩子节点。有几代人就有几个层次,层次最大值叫做这个家族的高度,生的孩子数目最多的叫做这个家族的

1.2 二叉树

二叉树,二叉树字面意思就是一个树只能分两个叉。左面的叉叫做左孩子,右面的叉叫做右孩子。就是每个节点最多只有两个子节点。

 

1.3 满二叉树

满二叉树和完全二叉树是经常晕的问题,有必要单独看一下。满二叉树就是如果一棵二叉树只有度为0的节点和度为2的节点,并且度为0的节点在同一层上,则这棵二叉树为满二叉树。

img

这棵二叉树为满二叉树,也可以说深度为k=4,有2^k-1=15个节点的二叉树。

1.4 完全二叉树

完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大 值,并且最下面一层的节点都集中在该层最左边的若干位置。

  • 结点按照编号从左到右依次构建二叉树,不存在无左孩子、却有右孩子的情况(有就不是)

  • 满二叉树一定是完全二叉树,完全二叉树不一定是满二叉树

image.png

前面两棵树的前n-1层都是满的,最后一层所有节点都集中在左侧区域,而且节点之间不能有空隙。最后一个为什么不是?因为有一节点缺了一个左子节点。

 

2. 二叉树的性质

  1. 层节点: 在二叉树的第i层上最多有2^{i-1}个结点(i>=1)

  2. 总结点: 深度为k的二叉树最多有2^{k}-1个结点(k>=1)

  3. 深度:具有n个结点的完全二叉树的深度必为 log2(n+1)

  4. 节点数:对于任意一棵二叉树,度为0的结点数等于度为2的结点数+1。

  5. 完全二叉树:若从上至下、从左至右编号,则编号为i 的结点,其左孩子编号必为2i,其右孩子编号必为2i+1;其双亲的编号必为i/2(i=1 时为根,除外)

 

3. 二叉树的遍历方式

二叉树有两种遍历方式:

  • 深度优先遍历:先往深走,遇到叶子节点再往回走。

  • 广度优先遍历:一层一层的去遍历,一层访问完再访问下一层。

深度优先遍历有四种方式,分别是 先序遍历、中序遍历、后序遍历、层次遍历

3.1 前序遍历

算法讲解

  • 遍历顺序:根结点->左子树->右子树

  • 先序遍历就像一个小人从根结点开始,围绕二叉树的外圈开始跑(遇到缝隙就钻进去),按照跑的顺序,依次输出序列

3.2 中序遍历

算法讲解

  • 遍历顺序:左子树->根结点->右子树

  • 中序遍历就像投影仪一样,将二叉树从最左侧到最右侧依次投影到同一水平线上面,得到的从左到右的相关序列就是二叉树的中序遍历


3.3 后序遍历

后序遍历就是在先序遍历的基础之上,进行像剪葡萄一样的操作

算法讲解

  • 遍历顺序:左子树->右子树->根结点

  • 后序遍历也是按照先序遍历的顺序输出,不过后序遍历就像剪葡萄,只能一个个剪,不能让超过1个的葡萄一起掉下来,那就错了。


3.4 层次遍历

8.png

算法讲解 就是一层一层的从左至右输出,算法不要求掌握

拓展

  • 树的先根遍历==二叉树的先序遍历

  • 树的中根遍历==二叉树的后序遍历

  • 树的后根遍历==二叉树的中序遍历

4 通过序列复原二叉树

练习:

(1) 前序:1 2 3 4 5 6 8 7 9 10 11 12 13 15 14

(2) 中序:3 4 8 6 7 5 2 1 10 9 11 15 13 14 12

(3) 后序:8 7 6 5 4 3 2 10 15 14 13 12 11 9 1

4.1 前中序列复原二叉树

(1) 前序:1 2 3 4 5 6 8 7 9 10 11 12 13 15 14

(2) 中序:3 4 8 6 7 5 2 1 10 9 11 15 13 14 12

  • 第一次遍历

根据前序的第一个节点为 1,可知此树的节点为 1。 接下来发现在 中序遍历中 1 在中间,然后将树结构进行拆分

(1) 前序:1【 2 3 4 5 6 8 7】【 9 10 11 12 13 15 14】

(2) 中序:【3 4 8 6 7 5 2】1【 10 9 11 15 13 14 12】

拆分完之后,根据中序遍历的三个部分,左边括号内的为 左子树部分,中间为根节点,右边括号内为 右子树部分

然后根据左边节点来画出左子树

最终结果图:

 

 

4.2 中后序列恢复二叉树

(2) 中序:3 4 8 6 7 5 2 1 10 9 11 15 13 14 12

(3) 后序:8 7 6 5 4 3 2 10 15 14 13 12 11 9 1

  • 第一次遍历

知道后续的最后一个节点就是根节点,所以根节点为 1

然后根据根节点对中序和后序进行拆分

(2) 中序:【3 4 8 6 7 5 2 】1【10 9 11 15 13 14 12】

(3) 后序:【8 7 6 5 4 3 2 】【10 15 14 13 12 11 9】 1

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值