数据结构第五章树和二叉树-严军勇.ppt
《数据结构第五章树和二叉树-严军勇.ppt》由会员分享,可在线阅读,更多相关《数据结构第五章树和二叉树-严军勇.ppt(94页珍藏版)》请在三一办公上搜索。
1、第5章 树和二叉树,本章要点 树的定义及相关术语 二叉树的定义、存储结构和基本运算的实现 二叉树的遍历、二叉树与树和森林的相互转换 哈夫曼树及应用 本章难点 二叉树的定义、存储结构和基本运算的实现 哈夫曼树及应用,1领会树和二叉树的类型定义,理解树和二叉树的结构差别。2熟记二叉树的主要特性,并了解它们的证明方法。3熟练掌握二叉树的各种遍历算法,并能灵活运用遍历算法实现二叉树的其它操作。4理解二叉树的线索化过程以及在中序线索化树上找给定结点的前驱和后继的方法。5熟练掌握二叉树和树的各种存储结构及其建立的算法。6学会编写实现树的各种操作的算法。7了解最优树的特性,掌握建立最优树和赫夫曼编码的方法。
2、,学习目标,5.1 树的定义和基本操作,5.1.1 树的定义前面章节讨论的数据结构主要是线性结构。树型结构是一类重要的非线性结构。非线性结构结构中存在一个数据元素有两个或两个以上的直接前驱(或直接后继)元素。树型结构广泛用于描述家族谱系以及其它社会组织结构。在计算机领域中,如操作系统的文件目录结构、编译程序中的语法结构和数据库中的信息组织也都需要借用树来描述。本章将讨论树和二叉树两种树型结构。,树的定义树是n(n0)个具有相同特性的数据元素的结点的有限集合。当n=0时,称为空树(用 表示)。有且仅有一个称为根(root)结点的数据元素,根结点没有前驱结点。当n1时,其余结点可分为 m(m0)个
3、互不相交的(非空)有限集 T1,T2,Tm,其中每一个子集本身又是一棵符合本定义的树,称为根 root 的子树。树的定义是一个递归定义,它反映了树的固有特性,一棵树是由根和它的子树构成,而子树又由子树的根和更小的子树构成。,5.1.1 树的定义,5.1.1 树的定义,(a)空树,(b)只有根结点的树,(d)非树结构,(c)一般的树,(a)空树。(b)只有根结点的树。(c)有11个结点的树是根结点,其余结点分成三个不相交的子集。T1=BT2=C,E,F,G,H,I,J,KT21=E,I,JT22=FT23=G,K T24=HT3=D(d)非树结构。,5.1.1 树的定义,(c)一般的树,树的特性
4、 树的根结点没有前驱结点,除根结点之外的所有结点有且只有一个前驱结点。树中所有结点可以有零个或多个后继结点。,5.1.1 树的定义,5.1.1 树的常用术语,结点的度结点拥有的子树的个数。叶子结点(终端结点)度为0的结点。分支结点(非终端结点)度不为0的结点。树的度树内各结点的度的最大值。双亲结点结点的直接前驱结点。,(c)一般的树,孩子结点一个结点的直接后继结点。兄弟结点同一双亲结点的孩子结点之间互称兄弟结点。祖先结点从根结点到该结点所经分支上的所有结点。子孙结点以某结点为根的子树中的任一结点都称为该结点的子孙结点。结点的层次根为第一层,根的直接后继为第二层,依次类推。,5.1.1 树的常用
5、术语,(c)一般的树,树的深度(高度)结点的层次从根结点开始,根为第一层,根的孩子为第二层,树中结点的最大层次称为树的深度或高度。有序树、无序树如果一棵树中的结点的各子树从左到右是有次序的,即若交换了某结点各子树的相对位置,则构成不同的树,称这棵树为有序树;反之,则称为无序树。森林m棵互不相交的树的集合。一棵树可以看成是由根结点和根结点下的森林构成的。,5.1.1 树的常用术语,(c)一般的树,直观表示法 嵌套集合表示法,5.1.3 树的表示方法,直观表示法,嵌套集合表示法,括号形式表示法(A(B),C(E(I),(J),(F),(G(K),(H),(D)凹入表示法,A,B,C,E,I,J,F
6、,G,K,H,D,5.1.3 树的表示方法,就结构中数据元素之间存在的关系可将树和线性结构作如下对照:,将树和线性结构数据元素之间存在的关系作如下对照:,可见,由于线性结构是一个“序列”,元素之间存在的是“一对一”的关系,而树是一个层次结构,元素之间存在的是“一对多”的关系。,5.1.3 树的表示方法,二叉树是另一种基本的树型结构。用二叉树来研究树的问题是表示和处理树型结构的基本方法。二叉树的定义二叉树是有限个元素的集合,该集合或者为空,或者由一个称为根的元素及两个互不相交的,被分别称为左子树和右子树的二叉树组成。当集合为空时,称该二叉树为空二叉树。约定:二叉树的每个结点至多只有二棵子树,即二
7、叉树中不存在度大于2的结点。二叉树是有序的,如果将左右子树颠倒,就成为另一棵二叉树。,5.2二叉树,二叉树的定义,二叉树具有以下5种基本形态。,空二叉树,仅有根的二叉树,仅有左子树的二叉树,仅有右子树的二叉树,左、右子树均非空的二叉树,二叉树并非是树的特殊情形,在二叉树中,即使是一个孩子,也有左右之分。具有2个结点的二叉树有2种形态,具有3个结点的二叉树有5种形态。2种特殊的二叉树 满二叉树如果二叉树中所有的分支结点的度数都为2,且叶子结点都在同一层次上,则称这类二叉树为满二叉树。对满二叉树从上到下从左到右进行从1开始的编号(如图所示),则深度为k的满二叉树有且必有2k-1个结点。这种二叉树的
8、特点是每一层上的结点数都是最大的结点数。,二叉树的定义,满二叉树,非满二叉树,二叉树的定义,二叉树的定义,完全二叉树如果一棵包含 n 个结点的二叉树中每个结点都可以和满二叉树中编号为1至 n 的结点一一对应,则称这类二叉树为完全二叉树。,完全二叉树,非完全二叉树,二叉树的性质,性质1:一棵非空二叉树的第i层上至多有 2i-1 个结点(i1)。性质2:深度为k的二叉树中至多含有 2k-1 个结点,(k1)。性质3:对任何一棵二叉树 T,如果叶子结点数为n0,度为2的结点数为 n2,则n0=n2+1性质4:具有n个结点的完全二叉树的深度为 log2n+1。,性质5:如果具有 n 个结点的完全二叉树
9、(其深度为 log2n+1)的结点按自上而下和从左到右的顺序对每个结点从1起开始顺序编号,则对任一编号为 j 的结点(1jn),有 若j=1,则结点j是二叉树的根,无双亲,否则其双亲结点 parent(j)是 j/2。若 2jn,则结点j 的左孩子结点是 2j,否则无左孩子,即编号为j且满足2jn的结点为叶子结点。若2j+1 n,则结点为j的右孩子结点是2j+1,否则无右孩子。若结点j序号为奇数且不等于1,则它的左兄弟为j-1。若结点j序号为偶数且不等于n,它的右兄弟为j+1。,二叉树的性质,二叉树的性质,例已知一棵完全二叉树共有892个结点,求 树的高度 叶子结点数 单支结点数 最后一个非终
10、端结点的序号答 已知深度为k的二叉树最多有2k-1个结点(K1),29-1892 210-1,故树的高度为10 对于完全二叉树来说,度为1的结点只能是0或1因为n=n0+n1+n2和n0=n2+1得:设n1=0,892=n0+0+n2=2n2+1得n2不为整数出错设n1=1,892=n0+1+n2=2n2+2得n2=445 n0=n2+1=446叶子结点数为446。,二叉树的性质,答 由得单支结点数为1 对于n个结点的完全二叉树,最后一个树叶结点,即序号为n的叶结点其双亲结点 即为最后一个非终端结点,序号为892/2=446。,二叉树的存储结构,顺序存储结构用一组地址连续的存储单元存储二叉树中
11、的数据元素。二叉树的顺序存储结构的定义如下:#define MAX 100/*暂定二叉树中结点数的最大值为100*/typedef struct Elemtype aMAX;int count;/*二叉树中结点数*/BTree;/*二叉树的顺序存储结构*/typedef BTree bt;,按照数据结构的“顺序存储映象”的定义,在顺序存储结构中没有附加信息,因此对二叉树的顺序存储结构,也只是以一组地址连续的存储空间存放二叉树中的数据元素。只是不能以“存储位置相邻”来表示“后继”关系。在二叉树的这种表示方式下,各结点之间的逻辑关系是隐含表示的。完全二叉树中,除最下面一层外,各层都充满结点。除最底
12、层外,每一层的结点个数恰好是上一层结点数的2倍。故从一个结点的编号可推出其双亲、左右孩子和兄弟等结点的编号。完全二叉树中结点的层次关系可反映结点之间的逻辑关系。,二叉树的存储结构,为了能在存储结构中反映出结点之间的逻辑关系,必须将二叉树中结点依照一定规律安排在这组存储单元中。对于完全二叉树,只要从根起按层序存储即可。根据上一节所述完全二叉树的特性,将完全二叉树上编号为 i 的结点元素存储在一维数组中下标为 i-1 的分量中,如前例含12个结点的完全二叉树的顺序存储结构如下所示。,二叉树的存储结构,根据上节所述二叉树的性质5,可推出顺序存储结构中“双亲”和“孩子”的关系:假设 bt.ai 是完全
13、二叉树上的一个结点,若 2i+1bt.count,则 bt.a2i+1 是它的左孩子,否则它的左子树为空树;若 2i+2bt.count,则 bt.a2i+2是它的右孩子,否则它的右子树为空树。在二叉树表示方法下,各结点间的逻辑关系是隐含的。完全二叉树中,除最底层外,各层都充满结点;除最底层外,每一层结点数恰好是上一层结点数的2倍,故从一个结点的编号就可推得其双亲、左右孩子和兄弟结点的编号。,数组下标,二叉树的存储结构,二叉树的存储结构,对于结点i 仅当i=1时,结点i为根结点。当i1时,结点i的双亲结点为。结点i的左孩子结点2i。结点i的右孩子结点2i+1。当i为奇数且不为1时,结点i的左兄
14、弟为i-1。当i为偶数且小于n时,结点i的右兄弟为i+1。完全二叉树中结点的层次关系反映了结点间的逻辑关系,对于完全二叉树,顺序存储既方便又节省存储空间。,二叉树的存储结构,对于一般的二叉树,采用顺序存储时,为了用结点在数组中的位置表示结点之间的逻辑关系,也必须按完全二叉树的形式来存储树中的结点。在最坏情况,一个只有k个结点的右单支树却需要2k-1个结点的存储空间。,右单支二叉树,对应的完全二叉树,10,13,二叉树的存储结构,顺序存储对于完全二叉树来说非常方便。对于一般的二叉树,可对照完全二叉树的编号进行相应的存储,但在没有结点的分量中需填充空白字符。显然,这种存储表示方法只适合于完全二叉树
15、,对于一般的二叉树将造成存储空间的很大浪费。因此二叉树的常用存储结构是链表。,二叉树的存储结构,1,2,3,4,5,6,1,7,8,9,10,11,12,数组下标,对应的完全二叉树,一般二叉树,序号,1,12,链式存储结构二叉树的链式存储结构指的是用链表来存储二叉树,即用结点结构中的指针域来表达数据元素之间的关系。二叉树的二叉链表存储结点结构 typedef struct node Elemtype data;struct node*LChild,*RChild;/*左、右孩子指针*/BinNode,*BinTree;二叉树的结点由一个数据元素和指向左、右孩子的指针域。,二叉树的存储结构,在二
16、叉链表中虽然没有指向双亲结点的指针,但可以通过指向孩子结点的指针找到“双亲”,因此二叉链表中的信息是完备的。这和只有指向后继指针的单链表中隐含着“前驱”的信息是类似的。整个二叉树可以一个指向根结点的指针表示,如下列左图所示二叉树的二叉链表如下列右图所示。,头指针bt,二叉树的存储结构,基于二叉链表存储结构,建立二叉树算法分析输入时,按完全二叉树形式,若是非完全二叉树,必须给定一些假想结点,使之符合完全二叉树形式,存在的结点输入对应字符,不存在的结点输入逗号,以“#”为输入结束符。建成的二叉链表由根指针root惟一确定。,二叉树的存储结构,增加虚结点假想为完全二叉树,非完全二叉树,从键盘输入数据
17、为:AB,C,D#,二叉树的存储结构,头指针root,建立的二叉链表,二叉树的存储结构,在以前各章的类型定义中都有“遍历”的基本操作,但从来没有专门提出来讨论过。而从另一方面看,很多操作是在遍历过程中进行的,如,在线性表中查询某个特定的数据元素,求链表的长度等等。这是因为线性结构是一个“序列”,每个数据元素只有一个后继,因此它的遍历只有一条搜索路径,即从第一个数据元素起,顺着“后继”直到最后一个数据元素止。而非线性结构中每个数据元素可以有多个后继,为保证遍历成功就需要确定合适的搜索路径,二叉树的遍历,从数据类型的定义得知,“遍历”的含义是对结构中的每个数据元素都访问一次且仅仅访问一次。因此进行
18、遍历应该确定一条搜索路径,使得结构中的每个数据元素都出现在这条搜索路径上,才能确保每个数据元素都被访问到。由于二叉树中每个结点都有两个后继,则可以有三条搜索路径:先左(子树)后右(子树);先右(子树)后左(子树);按层次从上到下。按层次从上到下的遍历比较简单,先访问第一层的结点(即根结点),再访问第二层,第三层,直到最后一层,对每一层的结点则从左到右,即“先被访问的父结点的孩子结点”先于“后被访问的父结点的孩子结点”进行访问。,二叉树的遍历,从二叉树的结构定义得知,二叉树是由“根结点”、“左子树”和“右子树”三部分构成,则遍历二叉树的操作可分解为“访问根结点”、“遍历左子树”和“遍历右子树”三
19、个子操作,并且由二叉树的递归定义可知,遍历左子树和遍历右子树可如同遍历二叉树一样“递归”进行。因此整个遍历的操作只要在一条搜索路径上一次完成这三个子操作即可。,第一次走到根结点即“访问”为“先序遍历”,从左子树回来再“访问”为“中序遍历”,从右子树回来再“访问”为“后序遍历”。,二叉树的遍历,对二叉树进行遍历的先左后右的搜索路径,可得到两个结论:由于左右子树互不相交,因此对左子树的遍历一定不会访问到右子树上的结点,反之对右子树的遍历也一定不会访问到左子树,因此沿这条搜索路径必可实现对二叉树中每个结点都访问到且只访问一次;也正由于左右子树不相交,因此在遍历了左子树之后必须回到根结点才能继续遍历右
20、子树。由此可见,在这条搜索路径上从进入二叉树到离开二叉树,一共三次遇到根结点,因此访问根结点的操作可在任意一次也只能在其中一次进行。由此得到以下三个遍历二叉树的算法:,二叉树的遍历,按照遍历过程中先后访问的次序将二叉树中的结点排列起来分别得到二叉树的先序遍历、中序遍历和后序遍历。,二叉树的遍历,先序遍历(DLR)void PreOrder(BinTree r)/先序遍历以r为根指针的二叉树 if(r!=NULL)Visit(r-data);/*访问根结点*/PreOrder(r-LChild);/*先序遍历r的左子树*/PreOrder(r-RChild);/*先序遍历r的右子树*/,按先序遍
21、历得到结点序列:ABDCEF,二叉树的遍历,中序遍历(LDR)void InOrder(BinTree r)/中序遍历以r为根指针的二叉树 if(r!=NULL)InOrder(r-LChild);/*先序遍历r的左子树*/Visit(r-data);/*访问根结点*/InOrder(r-RChild);/*先序遍历r的右子树*/,按中序遍历得到结点序列:BDAEFC,二叉树的遍历,后序遍历(LRD)void PostOrder(BinTree r)/后序遍历以r为根指针的二叉树 if(r!=NULL)PostOrder(r-LCchild);/*先序遍历r的左子树*/PostOrder(r-
22、RChild);/*先序遍历r的右子树*/Visit(r-data);/*访问根结点*/,按后序遍历得到结点序列:DBFECA,二叉树的遍历,层次遍历指从二叉树的第一层(根结点)开始,从上到下逐层遍历,而在同一层中,则按从左到右的顺序对结点逐个访问。按层次遍历得到结点序列:ABCDEF算法设计设置一个队列结构,遍历从根结点开始,首先将根结点指针入队列,然后从队头取出一个元素,每取一个元素,执行下面操作:访问该元素所指结点。若该结点左、右孩子非空,则将左、右孩子指针顺序入队。当队列为空时,二叉树的层次遍历结束。,二叉树的遍历,表达式二叉树,可以把任意算术表达式由一棵二叉树表示。例:a*(b-c)
23、-d/e+fg表示如右图,称为表达式二叉树每个非叶子结点都是运算符,每个叶子结点都是操作数。前序:+-*a-bc/defg中序:a*(b-c)-d/e+fg后序:abc-*de/-fg+,二叉树遍历的应用,二叉树遍历的应用,中缀表达式是经常使用的表达式,前缀表达式和后缀表达式又分别称为波兰式和逆波兰式,其中后缀表达式就是在栈一章中提到的后缀运算式,后缀表达式在表达式计算中有非常重要的作用。,对任意一棵二叉树,其三种遍历序列是惟一确定的。但已知二叉树的遍历序列,能否确定二叉树?若已知三种遍历序列的其中一种,具有这种遍历序列的二叉树是多种多样的,不能唯一确定一棵二叉树。若已知先序和中序遍历序列,二
24、叉树可以惟一确定。若已知后序和中序遍历序列,二叉树可以惟一确定。如果只知道二叉树的先序和后序遍历序列,由于只能确定根结点,不能用根结点将其中的一个序列划分为左右子树,所以不能惟一地确定一棵二叉树。总之,由二叉树的遍历序列恢复二叉树时,必须至少已知两种编历序列,而且必须有中序序列。,二叉树遍历的应用,二叉树遍历的应用,例写出如图所示的二叉树的先序、中序和后序遍历序列。先序:fdbacegihj 中序:abcdefghij 后序:acbedhjigf,二叉树,二叉树遍历的应用,例若一棵树,左右子树均有三个结点,其左子树的先序序列与中序序列相同,右子树的中序序列与后序序列相同,试构造该树。解依题意,
25、左子树的先序与中序序列相同,即有先序:根左右中序:左根右即以左子树为根的树无左孩子。右子树的中序与后序序列相同,即有中序:左根右后序:左右根也即,以右子树为根的树无右孩子,由此构造该树如图所示:,二叉树,二叉树遍历的应用,例已知一棵二叉树的先蓄序列和中序序列分别为:先序ABCDEFGHI中序CBAEDGHFI试恢复该二叉树。解 由先序序列,A是二叉树的根结点,A将中序序列分为左子树B,C和右子树E,D,G,H,F,I,如图所示。在左子树中,由先序可知,结点B是根结点,由中序可知,C是左子树根结点,左子树完成。在右子树中,由先序可知,D是右子树的根结点,在右子树中序序列中,D将右子树分为左子树E
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 第五 二叉 严军勇
链接地址:https://www.31ppt.com/p-6578935.html