您的位置:首页 > 其它

树的基本概念及性质

2014-11-09 16:52 218 查看

树的定义:树是n个结点的集合,集合中有一个成为根的特殊结点,在根结点下分布着一些互不相交的集合,每个集合又是一个树,这些树成为根结点的子树。



上面的定义可以看出树采用了递归的描述,还有比较特殊的如空集合也是树,成为空树,即没有结点;单一结点是一棵树,树根就是该结点的本身。

在树中一个结点只有一个前驱,但有多个后继,树中有且仅有一个结点没有前驱,即树的根结点,,除了根结点,其余每个节点有且仅有一个前驱,每个结点可以有任意多个后继。

树的常见术语:

父结点,子结点,兄弟结点:每个结点的子树成为该结点的子结点(儿子),相应的该结点成为子结点的父结点(父亲),具有同一父结点的结点成为兄弟节点。上图中A是B,C,D的父结点,BCD是兄弟结点。

结点的度:一个结点的子树的数量称为结点的度,结点A有3个子树,A的度为3.

树的度:树中结点最大的度数,上图中树的度为3.

树的深度:指的是树的最大层数,上图中做大层数为4,则树的深度为4。

二叉树:一个二叉树是n个结点的集合,此集合要么是空集,要么是一个根结点加上分别成为左子树和右子树的两个互不交叉的二叉树。

由上述定义可知,二叉树的任意结点只能有两个子结点;如果只有一个子结点只能是左子树或是右子树

两种特殊的二叉树:一种是满二叉树,除最下一层的叶结点外,每层的结点都有2个子结点,这样就构成了满二叉树。 第二种是完全二叉树,除了二叉树最后一层外,其他各层的结点树都达到最大个数,且最后一层从左到右的结点连续存放,只缺右侧若干结点,这叫完全二叉树。满二叉树是完全二叉树,完全二叉树不一定是满二叉树;在完全二叉树中,若某个结点没有左孩子,则肯定也没有右孩子,则肯定是叶结点。

完全二叉树如下图:



二叉树的性质:

1.在二叉树中,第i层的结点总数最多有2i-1(i>=1)

对第一层:i=1,2的0次方为1,即根结点;对第n层,由于二叉树的每个结点至多有2个孩子,因此第n层的最大结点数是n-1层的2倍,即该层的最大结点总数为2的n-1次方,上图n=4,则最大结点总数为8

2.在深度为K的二叉树中最多有2的K次方减一个结点(K>=1),最少有K个结点。
若使深度为K的二叉树结点总数最多,则每一层的都含有最大结点数,由1性质得深度为K的二叉树结点总数最多为: 20+21+…+2k-1=2k-1。

3.对于一颗二叉树,如果叶结点数为n0,而度为2的结点总数为n2,则n0=n2+1。
二叉树中所有结点的度都不大于2,所以结点总数(n)等于0度结点数,1度结点数,2度结点数的和,即: n=no+n1+n2 (式子1)
一个度结点有一个孩子,2度结点有两个孩子,树中只有根结点不是任何结点的孩子,所以二叉树中的结点总数又表示为: n=n1+2n2+1
(式子2)

由1和2式得:n0=n2+1。
4.具有n个结点的完全二叉树的树的深度k为 [log2n]+1。
深度为K的完全二叉树的前k-1层是一个深度为k-1的满二叉树,该树有2k-1-1个结点。这样在第K层还有若干个结点m,即n=2k-1-1+m,即 n>2k-1-1。而由二叉树的性质又有: n≤2k-1。
即:2k-1-l<n≤2k-1

 由此可推出:2k-1≤n<2k,取对数后有:

k-1≤lgn<k

 又因k-1和k是相邻的两个整数,故有


,

 由此即得:



5.有n个结点的完全二叉树各结点如果用顺序方式存储,对任意结点i,有如下关系:

如果i!=1,则父结点的编号为i/2;
如果2*i<=n,则其左孩子的编号为2*i,若2*i>n,则无左子树,是叶结点,即2*i>n的结点肯定是叶结点,上图G结点编号为7,i=7,2*7>12,即i是叶结点;
如果2*i+1<=n,则其右孩子的编号为2*i+1,若2*i+1>n,则无右子树。

二叉树的存储:
1.顺序存储结构:一般是由一个一维数组构成的,二叉树上的结点按照某种规定的次序逐个保存到数组的各个单元
使用一维数组保存二叉树的结点,关键在于定义结点的存储次序,这种次序应该能反应结点之间的逻辑关系,即父子,兄弟等关系。

根据前面的性质可知:对于一完全二叉树,用顺序存储各个结点具有对应的关系。对于结点i,其父节点为i/2(若商不是整数,取整),其左子节点编号为2i,右子结点编号为2i+1,

1 2 3 4 5 6 7 8 9 10 11 12

ABCDEFGHI J KL
如果需要顺序存储的二叉树不是完全二叉树,这样结点和数组中的序号没有了对应的关系。解决的方法是:将非完全二叉树转化为完全二叉树,把缺少的及诶单虚设为无数据的结点(以“#”表示)

如下图:





从非完全二叉树转换为完全二叉树保存A到H8个结点,占用了15个结点空间,这就造成了结点空间的浪费,除此之外,对顺序二叉树做插入或删除结点操作时,通常需要移动大量的结点,所以顺序存储一般只用在存放完全二叉树。

2.链式存储:

使用链式存储结构比较符合二叉树的逻辑结构,一个结点由结点元素和两个分别指向左右子树的指针组成,这样的结构称:二叉链表结构。有时为了方便查找父结点,还再增加一个结点指针,这种结构称为三叉链表结构。

二叉链式结构

LSonDataRSon
typedef struct ChainTree
{
DATA data;     //元素数据
struct ChainTree *left;     //左子树结点指针
struct ChainTree *right;     //右子树结点指针
} ChainTreeType;
ChainTreeType *root=NULL       //定义二叉树根结点指针

对于二叉树,每个结点都有指向该结点的边,假设一个二叉树有n个结点,则有n-1条边(除了根结点其余各个结点有对应一条边),而按照二叉链式存储结构,一个结点有2n个指针域,其中n-1个用来指向自己的左右孩子,剩余n+1个指针域为空。

二叉链表从根结点开始很方便的找到左右孩子,但是找到父结点比较麻烦。

三叉链式结构

LSonDataRSonParent
typedef struct ChainTree
{
DATA data;     //元素数据
struct ChainTree *left;     //左子树结点指针
struct ChainTree *right;     //右子树结点指针
struct ChainTree *parent;  //父结点指针

} ChainTreeType;
ChainTreeType *root=NULL       //定义二叉树根结点指针
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: