第五章树和二叉树

来源:互联网 发布:免费的发型设计软件 编辑:程序博客网 时间:2024/05/17 15:21

第 5 章    树和二叉树

5.1   树的逻辑结构

树的定义

n(n≥0)个结点的有限集合。当n=0时,称为空树;任意一棵非空树满足以下条件:

⑴ 有且仅有一个特定的称为根的结点;

⑵ 当n>1时,除根结点之外的其余结点被分成m(m>0)个互不相交的有限集合T1,T2,… ,Tm,其中每个集合又是一棵树,并称为这个根结点的子树。

树的基本术语:

结点的度:结点所拥有的子树的个数。

树的度:树中各结点度的最大值。

叶子结点:度为0的结点,也称为终端结点。

分支结点:度不为0的结点,也称为非终端结点

孩子、双亲:树中某结点子树的根结点称为这个结点的孩子结点,这个结点称为它孩子结点的双亲结点;

兄弟:具有同一个双亲的孩子结点互称为兄弟。 

路径:如果树的结点序列n1, n2, …, nk有如下关系:结点ni是ni+1的双亲(1<=i<k),则把n1, n2, …, nk称为一条由n1至nk的路径;

路径上经过的边的个数称为路径长度。 

祖先、子孙:在树中,如果有一条路径从结点x到结点y,则x称为y的祖先,而y称为x的子孙

结点所在层数:根结点的层数为1;对其余任何结点,若某结点在第k层,则其孩子结点在第k+1层。

树的深度:树中所有结点的最大层数,也称高度。

层序编号:将树中结点按照从上层到下层、同层从左到右的次序依次给他们编以从1开始的连续自然数。

有序树、无序树:如果一棵树中结点的各子树从左到右是有次序的,称这棵树为有序树;反之,称为无序树。

森林:m (m≥0)棵互不相交的树的集合

树的遍历:从根结点出发,按照某种次序访问树中所有结点,使得每个结点被访问一次且仅被访问一次。 

5.2  树的存储结构

双亲表示法:用一维数组来存储树的各个结点(一般按层序存储),数组中的一个元素对应树中的一个结点,包括结点的数据信息以及该结点的双亲在数组中的下标。 

孩子链表表示法:把每个结点的孩子排列起来,看成是一个线性表,且以单链表存储,则n个结点共有 n 个孩子链表。这 n 个单链表共有 n 个头指针,这 n 个头指针又组成了一个线性表,为了便于进行查找采用顺序存储。最后,将存放 n 个头指针的数组和存放n个结点的数组结合起来,构成孩子链表的表头数组。  

双亲孩子表示法

孩子兄弟表示法

5.3 二叉树的逻辑结构

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

特点

⑴ 每个结点最多有两棵子树;

⑵ 二叉树是有序的,其次序不能任意颠倒。 

二叉树的基本形态:空二叉树

只有一个根结点

根结点只有右子树

根结点只有左子树

根结点同时有左右子树

特殊的二叉树:斜树

满二叉树

完全二叉树

二叉树的基本性质 

性质5-1 二叉树的第i层上最多有2i-1个结点(i≥1)。 

性质5-2   一棵深度为k的二叉树中,最多有2k-1个结点,最少有k个结点。 

性质5-3   在一棵二叉树中,如果叶子结点数为n0,度为2的结点数为n2,则有: n0=n2+1。 

性质5-4  具有n个结点的完全二叉树的深度为 log2n  +1。 

性质5-5    对一棵具有n个结点的完全二叉树中从1开始按层序编号,则对于任意的序号为i(1≤i≤n)的结点(简称为结点i),有: 

(1)如果i>1,则结点i的双亲结点的序号为  i/2;如果i=1,则结点i是根结点,无双亲结点。 

(2)如果2i≤n,则结点i的左孩子的序号为2i;

如果2i>n,则结点i无左孩子。 

(3)如果2i+1≤n,则结点i的右孩子的序号为2i+1;如果2i+1>n,则结点 i无右孩子。 

二叉树的遍历:指从根结点出发,按照某种次序访问二叉树中的所有结点,使得每个结点被访问一次且仅被访问一次。

5.4 二叉树的存储结构及实现

顺序存储结构

二叉树的顺序存储结构就是用一维数组存储二叉树中的结点,并且结点的存储位置(下标)应能体现结点之间的逻辑关系——父子关系。 

二叉链表:令二叉树的每个结点对应一个链表结点,链表结点除了存放与二叉树结点有关的数据信息外,还要设置指示左右孩子的指针。 

三叉链表:在二叉链表的基础上增加了一个指向双亲的指针域

中序线索链表的建立——构造函数

1. 建立二叉链表,将每个结点的左右标志置为0;

2. 遍历二叉链表,建立线索;

   2.1 如果二叉链表root为空,则空操作返回;

   2.2 对root的左子树建立线索;

   2.3 对根结点root建立线索;

      2.3.1 若root没有左孩子,则为root加上前驱线索;

      2.3.2 若root没有右孩子,则将root右标志置为1;

      2.3.3 若结点pre右标志为1,则为pre加上后继线索;

      2.3.4 令pre指向刚刚访问的结点root;

   2.4 对root的右子树建立线索。 

5.5  二叉树遍历的非递归算法

二叉树前序遍历的非递归算法:在前序遍历过某结点的整个左子树后,如何找到该结点的右子树的根指针。

解决办法:在访问完该结点后,将该结点的指针保存在栈中,以便以后能通过它找到该结点的右子树。 

5.6   树、森林与二叉树的转换

树转换为二叉树 

⑴加线——树中所有相邻兄弟之间加一条连线。 

⑵去线——对树中的每个结点,只保留它与第一个孩子结点之间的连线,删去它与其它孩子结点之间的连线。 

⑶层次调整——以根结点为轴心,将树顺时针转动一定的角度,使之层次分明。 

森林转换为二叉树 

⑴ 将森林中的每棵树转换成二叉树;

⑵ 从第二棵二叉树开始,依次把后一棵二叉树的根结点作为前一棵二叉树根结点的右孩子,当所有二叉树连起来后,此时所得到的二叉树就是由森林转换得到的二叉树。

二叉树转换为树或森林 

⑴ 加线——若某结点x是其双亲y的左孩子,则把结点x的右孩子、右孩子的右孩子、……,都与结点y用线连起来;

⑵ 去线——删去原二叉树中所有的双亲结点与右孩子结点的连线;

⑶ 层次调整——整理由⑴、⑵两步所得到的树或森林,使之层次分明。 

5.7    哈夫曼树及哈夫曼编码

哈夫曼树:给定一组具有确定权值的叶子结点,带权路径长度最小的二叉树。

哈夫曼树应用——哈夫曼编码

前缀编码:一组编码中任一编码都不是其它任何一个编码的前缀 。

前缀编码保证了在解码时不会有多种可能。

0 0
原创粉丝点击