1. 树的常见概念
1.1 树
树是一个有n个有限节点组成一个具有层次关系的集合,每个节点有0个或者多个子节点,没有父节点的节点称为根节点,也就是说除了根节点以外每个节点都有父节点,并且有且只有一个。
比如下面这张图:
请理清一下上面这张图的人物关系:
上面这张图只有一个根节点,祖父作为根可以叫做大根堆,而你作为根只能叫做小根堆。向下发散出不同的结点,一个结点下面连着几个线叫做度,而下面没有了结点就称为叶子。
同一层的叫兄弟结点,下一层的叫孩子节点。有几代人就有几个层次,层次最大值叫做这个家族的高度,生的孩子数目最多的叫做这个家族的度。
1.2 二叉树
二叉树,二叉树字面意思就是一个树只能分两个叉。左面的叉叫做左孩子,右面的叉叫做右孩子。就是每个节点最多只有两个子节点。
1.3 满二叉树
满二叉树和完全二叉树是经常晕的问题,有必要单独看一下。满二叉树就是如果一棵二叉树只有度为0的节点和度为2的节点,并且度为0的节点在同一层上,则这棵二叉树为满二叉树。
这棵二叉树为满二叉树,也可以说深度为k=4,有2^k-1=15个节点的二叉树。
1.4 完全二叉树
完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大 值,并且最下面一层的节点都集中在该层最左边的若干位置。
-
结点按照编号从左到右依次构建二叉树,不存在无左孩子、却有右孩子的情况(有就不是)
-
满二叉树一定是完全二叉树,完全二叉树不一定是满二叉树
前面两棵树的前n-1层都是满的,最后一层所有节点都集中在左侧区域,而且节点之间不能有空隙。最后一个为什么不是?因为有一节点缺了一个左子节点。
2. 二叉树的性质
-
层节点: 在二叉树的第i层上最多有2^{i-1}个结点(i>=1)
-
总结点: 深度为k的二叉树最多有2^{k}-1个结点(k>=1)
-
深度:具有n个结点的完全二叉树的深度必为 log2(n+1)
-
节点数:对于任意一棵二叉树,度为0的结点数等于度为2的结点数+1。
-
完全二叉树:若从上至下、从左至右编号,则编号为i 的结点,其左孩子编号必为2i,其右孩子编号必为2i+1;其双亲的编号必为i/2(i=1 时为根,除外)
3. 二叉树的遍历方式
二叉树有两种遍历方式:
-
深度优先遍历:先往深走,遇到叶子节点再往回走。
-
广度优先遍历:一层一层的去遍历,一层访问完再访问下一层。
深度优先遍历有四种方式,分别是 先序遍历、中序遍历、后序遍历、层次遍历
3.1 前序遍历
算法讲解
-
遍历顺序:根结点->左子树->右子树
-
先序遍历就像一个小人从根结点开始,围绕二叉树的外圈开始跑(遇到缝隙就钻进去),按照跑的顺序,依次输出序列
3.2 中序遍历
算法讲解
-
遍历顺序:左子树->根结点->右子树
-
中序遍历就像投影仪一样,将二叉树从最左侧到最右侧依次投影到同一水平线上面,得到的从左到右的相关序列就是二叉树的中序遍历
3.3 后序遍历
后序遍历就是在先序遍历的基础之上,进行像剪葡萄一样的操作
算法讲解
-
遍历顺序:左子树->右子树->根结点
-
后序遍历也是按照先序遍历的顺序输出,不过后序遍历就像剪葡萄,只能一个个剪,不能让超过1个的葡萄一起掉下来,那就错了。
3.4 层次遍历
算法讲解 就是一层一层的从左至右输出,算法不要求掌握
拓展
-
树的先根遍历==二叉树的先序遍历
-
树的中根遍历==二叉树的后序遍历
-
树的后根遍历==二叉树的中序遍历
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