1.树
在学习树之前,我们学习了顺序表,链表,栈,队列,这些都是一对一的数据结构,树是一种一对多的数据结构.
1.1树的概念
树是一种非线性的数据结构,它由n(n>=0)个有限结点组成一个具有层次关系的集合,n==0时称为空树.把它叫做树是因为它看起来像一颗倒挂的树,也就是它的根在上面,叶子在下面.
😜我们来看一看树有哪些特点:
- 有且仅有一个根节点(root),根结点没有前驱结点.
- 除根节点外,其余结点被分成M(M>0)个互不相交的有限集合T1,T2,T3…,其中每一个集合又是一颗树,称为根的子树(SubTree),每棵子树的根结点有且仅有一个前驱,可以有0或者多个后继.
🤩额外要注意的地方:
- 树是递归定义的,也就是树的定义中还用到了树.
- 子树之间不能有交集,否则就不是树了.
那我们来看一下不是树的情况:
这种情况下,C和D两个结点连通了,也就是子树之间有交集了,这就不是树了!
这种情况也不是树了!
这种情况就是一个正确的树的结构.
😊做一些补充:
- 子树是不相交的
- 除了根节点之外,每个结点有且仅有一个父结点
- 一个有N个结点的树有N-1条边
1.2 结点相关的特性
- 结点的度(Degree):一个结点含有的子树的个数
- 树的度:一棵树所有结点的度的最大值为树的度
- 叶子结点/终端结点:度为0的结点.(度不为0的结点称为分支结点)
- 结点的层次:从根结点开始,根结点所在的为第1层,根的子结点为第2层.
1.3 结点之间的关系
- 双亲结点/父结点:若一个结点含有子结点,那么该结点称为其子结点的父结点.
- 孩子结点/子结点:一个结点含有的子树的根结点称为该结点的子结点.
- 兄弟结点:具有相同父结点的结点互为兄弟结点
- 堂兄弟结点:双亲在同一层的结点互为堂兄弟结点
- 结点的祖先:从根到该结点所经分支上的所有结点.
- 子孙:以某结点为根的子树中任一结点都称为该结点的子孙.
1.4 树的表示形式
树有很多种表示方式:双亲表示法,孩子表示法,孩子双亲表示法,孩子兄弟表示法.最常用的是孩子兄弟表示法.
class Node{
int value;//结点存储的值
Node firstChild;//第一个孩子结点的引用
Node nextBrother;//孩子结点的兄弟结点的引用
}
我们设置两个结点引用,分别指向结点的第一个孩子和该孩子结点的右兄弟.
树的高度/深度:树中结点的最大层次
有序树和无序树:
有序树就是树中结点的子树从左往右看,谁在左边,谁在右边,是有规定的.在有序树中,一个结点最左边的子树称为"第一个孩子",最右边的子树称为"最后一个孩子".反之为无序树.
2.二叉树
那什么样的树是一棵二叉树呢?满足以下条件的就是二叉树.
- 本身是一棵有序树.有序也就是二叉树子树有左右之分,次序不能颠倒.
- 树中每个结点的度不能超过2,也就是只能是0,1,2.
也可以这样理解:
- 为空
- 由一个根结点和根结点的左子树和右子树组成.(左右子树均为二叉树)
这样一棵树就是二叉树
这样就不是一棵二叉树
🤷注意:对于任意的二叉树都是由以下几种情况复合而成的:
2.1 两种特殊的二叉树
😀满二叉树:每层的结点数都达到了最大值,则为满二叉树.也就是说,如果一棵二叉树的层数为K,且结点总数是2的K次方再减1,那它就是满二叉树.
比如:
😀完全二叉树:对于深度为K的,有N个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从0至N-1的结点"一一对应"时称为完全二叉树.换一种说法就是:如果二叉树除去最后一层结点为满二叉树,且最后一层的结点依次从左到右分布.(满二叉树是一种特殊的完全二叉树)
完全二叉树的例子:
非完全二叉树(只能算一个普通的二叉树)的例子:
😜从中我们也可以发现一些完全二叉树的特点:
如果一个完全二叉树的某一个结点没有右子树,那么一定没有左子树,有右子树就一定得有左子树,从左到右一定是连续的,中间不能出现空的.
注意:一个满二叉树一定是完全二叉树,但是完全二叉树不一定是满二叉树.
2.2 二叉树的性质
💛若规定根结点的层数为1,则一棵非空二叉树的第i层上最多有2的(i-1)次方个结点.
💛若规定只有根结点的二叉树的深度为1,则深度为K的二叉树的最大结点数是2的K次方减1.
💛对任何一棵二叉树,如果其叶子结点个数为N0,度为2的分支结点(非叶子结点)的个数为N2,则有N0=N2+1.
比如对于这样一棵二叉树:
叶子结点个数为3,分支结点个数为2,叶子结点的个数也就是分支结点的个数加1.
💛如果一棵二叉树的分支数为N,那么结点总个数就是N+1.
💛具有N个结点的完全二叉树的深度为log以2为底(N+1)向上取整.
💛对于具有N个结点的完全二叉树,如果按照从上到下,从左到右的顺序对所有的结点从0开始编号,那么对于编号为i的结点有如下特点:
- 😘如果i=0,那么i为根结点编号,无双亲结点.
- 😘如果i>0,那么它的双亲结点编号为(i-1)/2.
- 😘如果2i+1<N,那么编号为i的结点的左孩子编号为2i+1.如果2i+1>=N,那么就没有左孩子.
- 😘如果2i+2<N,那么右孩子的编号为2i+2.如果2i+2>=N,那么没有右孩子.
2.3 一些例题
🎈
思路:根据二叉树的性质–叶子结点个数等于度为2的结点的个数加1.也就是200.
😍补充一些二叉树的特点:
结点数为奇数的二叉树,没有度为1的结点.结点数为偶数的二叉树,有且仅有一个度为1的结点.
🎈
思路:树的结点总数为2N,说明结点总数为偶数个,那么度为1的结点只有1个,那么2N=N0+N1+N2,也就是总结点个数等于度分别为0,1,2的结点的个数之和,式子就变成了2N=N0+1+N0-1,所以N0等于N,选A.
🎈
思路:树的结点总数为奇数,说明没有度为1的结点,那么767=N0+N2,式子变成767=N0+N0-1,所以选B.
🎈
思路:具有N个结点的完全二叉树的高度为 log2(n+1)向上取整.
log2(531 + 1) == 9…,向上取整为10,答案就是B