二叉树(Binary Tree)是n(n>=0)个结点的有限集合,该集合或者为空集(空二叉树),或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树的二叉树组成。 如图就是一棵二叉树
(1)每个结点最多有两棵子树,所以二叉树中不存在度大于2的结点。 注意:不是只有两课子树,只有一棵或者没有都是可以的。
(2)左子树和右子树是有顺序的,次序不能颠倒。
(3)即使树中只有一颗子树,也要区分是左子树还是右子树。下图中两颗树是不同的两颗二叉树。
二叉树具有五种基本形态:
(1)空二叉树;(2)只有一个根结点;(3)根结点只有左子树;(4)根结点只有右子树;(5)根结点既有左子树又有右子树。
斜树:所有的结点都只有左子树的二叉树称为左斜树。所有的结点都只有右子树的二叉树称为右斜树。如上图3就是左斜树、图4就是右斜树。
满二叉树:在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上,这样的二叉树就称为满二叉树,如图:一棵深度为k且由(2^k)-1 (k>=1) 个结点的二叉树称为满二叉树。
满二叉树的特点有:
(1)叶子只能出现在最下一层。出现在其他层就不可能达到平衡。
(2)非叶子结点的度一定是2。
(3)在同样深度的二叉树中,满二叉树的结点个数最多,叶子树最多。
完全二叉树:
对一棵具有n个结点的二叉树按层序编号,如果编号为i(1<=i<=n)的结点与同样深度的满二叉树中编号为i的结点在二叉树中位置完全相同,则这棵二叉树称为完全二叉树,如图:
完全二叉树的特点:
(1)叶子结点只能出现在最下两层。
(2)最下层的叶子一定集中在左部连续位置
(3)倒数二层,若有叶子结点,一定都在右部连续位置。
(4)如果结点度为1,则该结点只有左孩子,即不存在只有右子树的情况。
(5)同样结点数的二叉树,完全二叉树的深度最小(同样适用于满二叉树)。
注意:满二叉树一定是棵完全二叉树,但完全二叉树不一定是满的。
满二叉树和完全二叉树的区别:
满二叉树就是每一层的叶子节点都是满的,而完全二叉树则是一棵这样的树:如果把它的所有n个节点从上到下,从左到右依次编号,那么与对应的完全二叉树是相同的。也就是说,完全二叉树像是把满二叉树的最后若干的元素去掉。
这类二叉树有一个特点:就是按照节点序号可以确定节点之间的父子关系:编号为i的节点的两个子节点序号是2*i和2*i+1;而编号为i的节点的父节点序号是i/2(整除)。所以可以通过数组来保存这类二叉树,这样它的操作会很方便。对于其他的二叉树,可以通过给那些缺失的节点补一个特殊的值来转化成完全二叉树。当然,如果补的节点太多,就得不偿失了。
二叉树的性质一 : 在二叉树的第i层上至多有2^(i-1)个结点(i>=1) —— 计算某个二叉树中某一层最多有多少个结点。
二叉树的性质二:深度为k的二叉树至多有(2^k)-1个结点(k>=1) —— 求一个二叉树最多有多少个结点。
二叉树的性质三:对任何一棵二叉树,如果其终端结点(叶子结点)树为n0,度为2的结点数为n2,则n0=n2 + 1 —— 就是找一棵二叉树有多少个终端结点。
终端结点个数 = 结点度为2的结点总个数+1, 如下图, 有A 、B、C、D, 它们的度都为2, 那么 有4个结点, 4+1=5, 那么终端结点的个数就是5;
分支线总数=结点的总个数 - 1. 如下图的 结点的总个数为10, 10-1 = 9,分支线为9.
分支线总数 = 结点度为1 的总个数 + 2*(结点度为2的总个数);如下图, 结点度为1的,只有E, 结点度为2的,有A 、B、C、D, 那就是 1+2*4= 9;
结点的个数 = 分支线 总个数 +1; 如图: 分支线 9 +1 =10个结点。
结点的个数 = 结点度为0的总个数 + 结点度为1的总个数 + 结点度为1的总个数。 如图: 结点度为0的有5, 结点度为1的有1个,结点度为2的,有4个, 5+1+4=10个结点。
结点的个数 = 结点度为1的总个数 + 2*(结点的度为2的总个数)+1, 如图: 结点度为1的。有一个E, 结点度为2的,有4个。 那么就是 1+2*4+1=10个结点。
二叉树的性质四:具有n个结点的完全二叉树的深度为:⌊log₂n⌋+1 (⌊log₂n⌋取log₂n的下限), 这个公式同样适合求满二叉树的深度 —— 简单地说就是求一颗 满二叉树 和 完全二叉树的 深度,
证明:由满二叉树的定义结合性质二我们知道,深度为k的满二叉树的结点树n一定是2^k-1 个结点。
那么对于满二叉树我们可以通过n=2^k-1倒推得到满二叉树的深度为:
k=log₂(n+1)
由于完全二叉树前边我们已经提到,它的叶子结点只会出现在最下面的两层,我们可以同样如下推导
那么对于倒数第二层的满二叉树我们同样很容易回推出它的结点数为n=2^(k-1)-1,也可以使用 二叉树的性质1,计算
所以完全二叉树的结点数的取值范围是:2^(k-1)-1 < n <= 2^k-1
由于n是整数,n <= 2^k-1可以看成n < 2^k
同理2^(k-1)-1 < n可以看成2^(k-1) <= n
所以2^(k-1) <= n < 2^k
不等式两边同时取对数,得到k-1<=log₂n
由于k是深度,必须取整,所以k=⌊log₂n⌋+1
二叉树的性质五:如果对一棵有n个结点的完全二叉树(其深度为⌊log₂n⌋+1)的结点按层序(从左到右)编号,对任一结点i(1<=i<=n)有以下性质:
如果i = 1,则结点 i 是二叉树的根,无双亲; 如果i > 1,则其双亲是结点⌊i / 2⌋ —— 就是求一个结点的双亲 = 第 i 个结点 / 2.
求某个节点的双亲 = 如果是左子树 / 2; 如图: 结点8*2=4, 4 结点就是8 的双亲。
求某个节点的双亲 = (如果是右子树 - 1) / 2; 如图: 结点 ( 9 -1 )/ 2 =4。 4 结点就是9 的双亲。
如果2i > n,则结点 i 无左孩子(结点 i 为叶子结点);否则其左孩子是结点2i. —— 就是求某个结点的 左孩子。
某个结点的左孩子 = 2*i。如果结点2, 2*2 =4 , 结点 4就是它的左孩子。如果 2*i 大于结点个数,那么该结点既没有左孩子,也没有右孩子, 该结点是个叶子节点。 如图: 结点6 *2 =12; 超过结点个数10 ,所以结点6是个叶子结点。
同样,而结点5, 因为 2 *5 =10 ;正好是结点总数10 , 所以它的左孩子是 10;
如果2i+1 > n,则结点 i 无右孩子;否则其右孩子是结点2i+1 。 —— 就是求一个结点的右孩子;
某个结点的右孩子 = 2 *i + 1;如图: 结点4 * 2 +1=9, 结点9就是它的右孩子。如果 某个结点 2 *i + 1 大于 结点的个数, 那么该结点就没有右孩子; 比如结点5* 2 +1 =11; 所以该结点没有 右孩子。