树的基础知识
定义
树(Tree) 是n(n>=0)个结点的有限集。若n=0,则称为空树。若n>0 则满足:(1)在任何一棵非空树中,有且只有一个特定的称为 根(root) 的结点;(2)其余结点可分为m(m>0)个 互不相交 的有限集,其中每一个集合又是一棵树,并且成为 根的子树(SubTree)。
树的其他表示方法:
基本术语
根节点:非空树中无前驱结点的结点;
结点的度:结点拥有的子树数;
树的度:树内各结点度数的最大值;
叶子结点:终端结点,度数为0;
分支结点:非终端结点,度数不为0;
内部结点:根结点以外的分支结点;
结点子树的根结点称为该结点的孩子,该结点称为孩子的双亲;
拥有相同双亲的结点称为兄弟,双亲在同一层的结点称为堂兄弟;
祖先:从根到该结点所经分支上的所有结点;
子孙:以某结点为根的子树的任一结点;
树的深度:树中结点的最大层次;
有序树: 树中结点的各子树从左至右有次序(最左边的为第一个孩子)。
无序树:树中结点的各子树无次序。
森林:是m(m>=0)棵互不相交的树的集合。把根结点,删除树就变成了森林。一棵树可以看作是一个特殊的森林。给森林中的各子树加上一个双亲结点,森林就变成了树。
树的性质
(1)n个结点的树有n-1条边
(2)树中结点数等于所有结点的度数的和再加1
证明:分析有对于第i层结点数(i>1)等于第i-1层的度数和,则以此类推,由于根节点无上一层,则度数等于结点数减1,得证。
(3)度为K的树中第i层上至多有K^(i-1)个结点(i≥1)
证明:树的度为K,则结点最大度数为K,则设所有结点度数为K(叶子结点除外),则第1层结点数为1,第二层结点数为K,第三层结点数为K*K,以此类推,则第i层结点数为K^(i-1),得证。
(4)高度为h(h>1)的m叉树至多有(m^h)-1)/(m-1)个结点,至少有h个结点
证明:设每个结点的度数为1,则至少有h个结点,设每个结点度数为m,则第i层有m^(i-1)个结点数(i<=h),故等比数列求和的(m^h)-1)/(m-1),得证。
(5)具有n个结点的m叉树的最小高度为log(n(m-1)+1)对m取对数向上取整
证明:由性质四结论倒推
(6)高为h,度为 k的树至少有h+k-1个结点
证明:设只有一个结点度数为K,其他为1(叶子结点除外),则由性质四得,在h的基础上再加上k-1个结点,则至少有h+k-1个结点。
二叉树
定义
二叉树是n(n>=0)个结点的有限集,它或者是空集(n=0),或者是由一个根结点及两颗互不相交的分别称作这个根的左子树和右子树的二叉树组成
(1)每个结点最多有两个孩子(二叉树中不存在度数大于2的结点);
(2)子树有左右之分,且次序不能颠倒;
(3)二叉树可以是空集合,根可以有空的左子树或空的右子树;
二叉树不是树的特殊情况,二叉树和树是两个概念,是两种不同的树形结构:
二叉树结点的子树要区分左子树和右子树,即使只有一棵子树也要进行区分,说明它是左子树还是右子树。
树当结点只有一个孩子时,就没有需要区分左右次序了,因此这就是二叉树和树的区别。二叉树也不是度数为2的有序树。
二叉树的五种基本形态
使用原因
(1)二叉树结构最简单,规律性最强;
(2)所有树都可以转化为唯一对应的二叉树;普通树若不转化为二叉树,则运算很难实现;
二叉树的性质
(1)在二叉树的第i层上至多有2^(i-1)个结点。至少有1个结点。
(2)深度为k的二叉树至多有2^k-1个结点。至少有k个结点。
(3)对任意一棵二叉树T,如果叶子树为i,度数为2的结点数为j,则i=j+1。
证明:设T的总边数为B,总结点数为n,度数为2的结点数为j,度数为1的结点数为k,度数为0的结点数为i,则B=n-1;而B=j*2+k*1+i*0;则i+j+k-1=j*2+k*1。可得i=j+1;
二叉树两种特殊形式
满二叉树
一棵深度为K且有2^K-1个结点的二叉树称为满二叉树。
(1)每一层结点数都是最大结点数(即每一层都满结点);
(2)叶子结点都在最底层;
对满二叉树结点位置进行编号:从根结点开始,自上而下,从左到右。每一个结点都有元素。
完全二叉树
深度为K的具有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号为1~n的结点一一对应,称之为完全二叉树。
在满二叉树中,从最后一个结点开始,连续去掉任意个结点,得到一个完全二叉树
(1)叶子只可能分布在层次最大的两层上;
(2)对任一结点,如果其右子树最大层次为i,则其左子树最大层次数必为i或i+1;
完全二叉树性质
(1)具有n个结点的完全二叉树深度为[logn对2取对数]+1([X]表示不超过X的最大整数);
证明:
(2)如果对一颗有n个节点的完全二叉树(其深度为[logn对2取对数]+1)的节点按层序编号,对于任意节点i有:
1.如果i=1,则节点i是二叉树的根节点,无双亲;如果i>1,则其双亲节点是[i/2];
2.如果2i>n,则节点i无左孩子;否则其左孩子就是2i;
3.如果2i+1>n,则节点i无有右孩子;否则其右孩子就是2i+1;
二叉树的存储结构
顺序存储
按照满二叉树的结点层次编号,依次存放二叉树中的元素数据。
代码表示:
#define MAXSIZE 100
typedef int SqBiTree[MAXSIZE];
SqBiTree BT;
特点:结点间的关系蕴含在其存储位置中。浪费空间,适用于满二叉树和完全二叉树。
链式存储
二叉链表
结点特点:
代码表示:
typedef struct BiNode {
int data;
struct BiNode* Left, * Right;
}BiNode,*BiTree;
在n个结点的二叉链表中,有n+1个空指针域。
三叉链表
相对于二叉链表,加了一个Parent指针,可以指向双亲。
代表表示:
typedef struct TriBiNode {
int data;
struct BiNode* Left,*Parent, * Right;
}TriBiNode, * TriBiTree;