树是一种非常重要的结构.一提到树顾名思义就想到自然界的树,从根出来一个大树杆,然后就是分支,分支又有子分支,(分支的胳肢窝里可能有鸟窝),枝头最终点就长出叶子来(还有可能结出果,长出花来).
不过我们平常用树结构时都是树的倒序结构,就是根在上,分支和叶子在下面.这符合我们从简单到复杂,从少到多的习惯性认知思维.
我们平常看到的书的目录是树结构,windows上文件系统是以树形结构展示的.面向对象中的类继承层次是树形结构,生物种类的分类图也是个巨大的树形结构....
树定义的一些术语
描述自然界的树可以用一些生物术语,或用散文诗歌的优美语言.计算中使用的树形结构自然是最适合用自然语言和数学这门优美的语言了啊.
树的定义:树(tree)是n(n>=0)个结点的集合.n为0自然是表示一棵空树.一棵非空树有如下性质:
有且只有一个特定的结点,称为根结点(root)
根结点的子结点又可以组成一些互不相交的树.实际上树的定义就是一个递归定义的过程.无数小树组合成大树.
实际上平时用的基本类型,比如int,float之类的,我们可以看作一个只有一个结点的树.而线性结构可以看成每个结点只有一个子结点的树.
术语:
结点:表示树中的元素
结点的度:拥有子结点个数
叶子:度为0的结点,也称终端结点
孩子:一个结点的子结点称为它的孩子
双亲:孩子上面的结点,一般我们叫父结点.
兄弟:拥有相同父结点的结点叫兄弟结点
树的度: 挑出所有结点中那个度最大的用来代表树的度
结点的层次: 根结点是第一层,它的孩子结点就是第2层,依此类推
深度: 最大层次数即为深度
二叉树
二叉树是一种特殊的树.所有结点的度数不超过2的树称为二叉树.
二叉树中特殊的又有满二叉树(除了叶子结点外所有结点度为2,所有叶子结点在同一层),完全二叉树(叶子结点只可能出现在最后一层或倒数第二层.每个非叶子结点要么有两个孩子结点,要么就只有左孩子结点).
不过关于满二叉树的定义不是统一的,有分歧.有些人认为任何非叶子结点都有两个结点就是满二叉树了.
性质1:
在二叉树的第N层上,最多有2^(N-1)个结点.(2的N-1次方)
因为每个结点子结点最多为2.所以下一层最多是上一层的2倍.根结点为1(2的0次方),第2层最多2,第3层最多4...
性质2:
深度为H的二叉树最多有2^H - 1个结点(2的H次方减1)
由性质1可以推算出来
性质3:
对于任何二叉树,度为0(叶子结点)的结点数为N0,则度为2的结点数为N2 = N0 - 1;(度为1的结点数与它们的关系推不出来)
证明:假如结点总数为N,度为1的结点数是N1.则有
N = N0 + N1 + N2;这是结点之间的关系.那你就想度的总数(D)是结点的总数啥关系.你画个树瞧瞧会发现N = D + 1;可以把节点之间连线看成一个度.于是
N = D + 1; 而度数D = N0*0 + N1*1 + N2*2;
上面三个式子一结合就得出N0 = N2 + 1;
上面说到的3个性质我们在写代码时一般没怎么用到.但性质4写代码时经常用.
性质4:
如果有一棵完全二叉树,所有结点按层次从左至右排序(这里假设从0至N,一些书上是按1至N,但是我们用数组表示树时不方便,因为数组的下标可是从0开始的)
(1)设某结点的序号为n.如果n为0则自然是根结点.如果n不为0,则该结点的父结点为n/2;
(2)如果该结点是非叶子结点,则它的左孩子结点为2n + 1;右孩子结点为2n + 2;
(3)如果n > N/2 - 1则该结点无右孩子,如果n > N/2 则该结点无左孩子(自然也无右孩子),也就是叶子结点.结合(2)可推出如果符合此条件还有孩子则孩子的序号超出N了.