数据结构之二叉树(概念)

来源:互联网 发布:中国软件外包印度差距 编辑:程序博客网 时间:2024/05/16 12:04

树的定义:

树是n个结点的有限集。 n = 0 称为空树。如果n>0,则:

(1)有一个特定的称之为根的结点,它只有直接后继,但没有直接前驱。

(2)除根以外的其他结点划分为m个互不相交的有限集合,每个集合又是一棵树,并且称之为根的子树。每棵子树的根节点有且仅有一个直接前驱,但可以有0个或多个直接后继。

 

与树相关的定义:

节点:表示树中的元素,包括数据元素的内容及其指向其子树的分支。

节点的度:节点的分支数。

终端节点(叶子节点):度为0的节点。

非终端节点:度不为0的结点。

节点的层次:树中根节点的层次为1,根节点子树的根为第二层,以此类推。树中结点的最大层次称为树的深度或高度。

有序树、无序树:如果树中每棵子树从左向右的排列拥有一定的顺序,不得互    换,则称为有序树,否则称为无序树。

 

在树结构中,节点之间的关系又可以用家族关系描述。

(1)孩子、双亲:某个结点的子树称为这个结点的孩子,而这个结点又被称为孩子的双亲。

(2)子孙:以某节点为根的子树中的所有节点都被称为该节点的子孙。

(3)兄弟:同一个双亲的孩子之间互为兄弟。

(4)堂兄弟:双亲在同一层的节点互为堂兄弟。

 

树的存储:双亲表示法  孩子表示法  双亲孩子表示法

 

1、二叉树的定义

     二叉树(Binary Tree)是n(n>=0)个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树的二叉树组成。

 

1.1 二叉树的特点 

     二叉树的特点有: 

     1)每个结点最多有两棵子树,所以二叉树中不存在度大于2的结点。注意不是只有两棵子树,而是最多有。没有子树或者有一棵子树都是可以的。 

     2)左子树和右子树是有顺序的,次序不能任意颠倒。 

     3)即使树中某结点只有一棵子树,也要区分它是左子树还是右子树

 

 1.2 特殊二叉树 

     1、斜树 

     所有的结点都只有左子树的二叉树叫左斜树。所有结点都是只有右子树的二叉树叫右斜树。这两者统称为斜树。 

     斜树有很明显的特点:就是每一层都只有一个结点,结点的个数与二叉树的深度相同。 这也叫树,与线性表结构不是一样?其实线性表结构就可以理解为是树的一种极其特殊的表现形式    

  

     2、满二叉树 

     在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上,这样的二叉树称为满二叉树。 单是每个节点都存在左右子树,不能算是满二叉树,还必须要所有的叶子都在同一层,这就做到了整棵树的平衡。

     满二叉树的特点是: 

     1)叶子结点只能出现在最下一层。出现在其它层就不可能达到平衡。 

     2)非叶子结点的度一定是2。 

     3)在同样深度的二叉树中,满二叉树的结点个数最多,叶子数最多 

 

     

    3、完全二叉树 

     对一棵具有n个结点的二叉树按层序编号,如果编号为i(1<=i<=n)的结点域同样深度的满二叉树编号为i的结点在二叉树中的位置完全相同,则这棵二叉树称为完全二叉树。 

     满二叉树一定是一棵完全二叉树,但完全二叉树不一定是满的。

 按照层序编号,出线位置编号空档,所以不是完全二叉树。尽管不是满二叉树,但是编号是连续的,所以它是完全二叉树。

     完全二叉树的特点: 

     1)叶子结点只能出现在最下两层 

     2)最下层的叶子一定集中在左部连续位置

     3)倒数二层,若有叶子结点,一定都在右部连续位置 

     4)如果结点度为1,则该结点只有左孩子,即不存在只有右子树的情况 

     5)同样结点树的二叉树,完全二叉树的深度最小

 

判断某二叉树是否是完全二叉树的办法:那就是看着树的示意图,心中默默给每个节点按照满二叉树的结构逐层顺序编号,如果编号出现空档,就说明不是完全二叉树。

 

 2、二叉树的性质 

    性质1:在二叉树的第i层上至多有2i-1结点(i>=1)

    性质2:深度为k的二叉树至多有2-1个结点(i>=1)

  性质3: 对于任何一棵二叉树T,如果其终端结点数位n0,度为2的结点数位n2,则n0=n2+1

终端节点数就是叶子节点数,而一颗二叉树,除了叶子节点外,剩下的就是度为1或2的结点数了。

    性质4:具有n个结点的完全二叉树的深度为|log2n| + 1(|x|表示不大于x的最大整数)

    性质5:如果对一棵有n个结点的完全二叉树(其深度为|log2n| + 1)的结点按层序编号(从第1层到第|log2n| + 1层,每层从左到右),对任一结点i(1<=i<=n)

    有:

        1)如果i=1,则结点i为二叉树的根,无双亲;如i>1,则其双亲是结点|i/2|

        2)如果2i>n,则结点i无左孩子(结点i为叶子结点);否则其左孩子是结点2i

        3)如果2i+1>n,则结点i无右孩子;否则其右孩子是结点2i+1

3、二叉树的存储结构

    3.1 二叉树的顺序存储结构

    二叉树的顺序存储结构就是用一维数组存储二叉数中的结点,并且结点的存储位置,也就是数组的下标要能体现结点之间的逻辑关系,比如双亲与孩子的关系、左右兄弟的关系等。

    先来看看完全二叉树的顺序存储,一棵完全的二叉树如下图所示。

    将这棵二叉树保存到数组中,相应的下标对应其同样的位置,如下图所示。

    当然,对于一般的二叉树,尽管层序编号不能反映逻辑关系,但是可以将其按完全二叉树编号,只不过,把不存在的结点设置为"^"而已。如下图所示,注意浅色结点表示不存在。

    考虑一种极端的情况,一棵深度为k的右斜树,它只有k个结点,却需要分配2k-1个存储单元空间,这显然是对存储空间的浪费所以,顺序存储结构一般只用于完全二叉树。

 

    

 

    3.2 二叉链表

    既然顺序存储适应性不强,就要考虑链式存储结构二叉树每个结点最多有两个孩子,所以为它设计一个数据域和两个指针域是比较自然的想法,称这一的链表叫做二叉链表

    以下是二叉链表的结点结构定义代码。

1

2

3

4

5

6

/* 二叉树的二叉链表结点定义 */

typedef struct BitNode                        /*结点结构*/

{

         ElemType data;                         /* 结点数据 */

         struct BitNode *lchild, *rchild;      /* 左右孩子结点指针 */

}BitNode, *BiTree;

     结构示意图如下所示。

 

data是数据域,lchild和rchild都是指针域,分别存放指向左孩子和右孩子的指针。

如果有需要,我们可以再增加一个指向其双亲的指针域,那样就称之为三叉链表。

 

参考:严蔚敏老师之《数据结构》、程杰之《大话数据结构》

 

0 0
原创粉丝点击