《数据结构第六章树和二叉树.pptx》由会员分享,可在线阅读,更多相关《数据结构第六章树和二叉树.pptx(123页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、6.1 树的类型定义树的类型定义6.2 6.2 二叉树的类型定义二叉树的类型定义6.3 二叉树的存储结构二叉树的存储结构6.4 二叉树的遍历二叉树的遍历6.5 线索二叉树线索二叉树6.6 树和森林的表示方法树和森林的表示方法6.7 树和森林的遍历树和森林的遍历6.8 哈夫曼树与哈夫曼编码哈夫曼树与哈夫曼编码第1页/共123页6.1 树的类型定义树的类型定义第2页/共123页数据对象数据对象 D:D是具有相同特性的数据元素的集合。是具有相同特性的数据元素的集合。若若D为空集,则称为空树;为空集,则称为空树;否则否则:(1)在在D中存在唯一的称为根的数据元素中存在唯一的称为根的数据元素root,(
2、2)当当n1时,其余结点可分为时,其余结点可分为m(m0)个互个互 不相交的有限集不相交的有限集T1,T2,Tm,其中每一其中每一 棵子集本身又是一棵符合本定义的树,棵子集本身又是一棵符合本定义的树,称为根称为根root的子树。的子树。数据关系数据关系 R:第3页/共123页ABCDEFGHIJMKL例如例如:第4页/共123页基基 本本 术术 语语第5页/共123页结点结点:结点的度结点的度:树的度树的度:叶子结点叶子结点:分支结点分支结点:数据元素+若干指向子树的分支分支的个数树中所有结点的度的最大值度为零的结点度大于零的结点DHIJM第6页/共123页(从根到结点的)路径:路径:孩子孩子
3、结点、双亲双亲结点、兄弟兄弟结点、堂兄弟祖先祖先结点、子孙子孙结点结点的层次结点的层次:树的深度:树的深度:由从根根到该结点所经分支和结点构成ABCDEFGHIJMKL假设根结点的层次为1,第l 层的结点的子树根结点的层次为l+1树中叶子结点所在的最大层次第7页/共123页任何一棵非空树是一个二元组 Tree=(root,F)其中:其中:root 被称为根结点,F 被称为子树森林森林:森林:是 m(m0)棵互不相交的树的集合ArootBEFKLCGDHIJMF第8页/共123页()有确定的根;()树根和子树根之间为有向关系。有向树:有向树:有序树:有序树:子树之间存在确定的次序关系。无序树:无
4、序树:子树之间不存在确定的次序关系。第9页/共123页对比对比树型结构树型结构和和线性结构线性结构的结构特点的结构特点第10页/共123页线性结构线性结构树型结构树型结构第一个数据元素第一个数据元素 (无前驱无前驱)根结点根结点 (无前驱无前驱)最后一个数据元素最后一个数据元素 (无后继无后继)多个叶子结点多个叶子结点 (无后继无后继)其它数据元素其它数据元素(一个前驱、一个前驱、一个后继一个后继)其它数据元素其它数据元素(一个前驱、一个前驱、多个后继多个后继)第11页/共123页6.2 二叉树的类型定义二叉树的类型定义第12页/共123页 二叉树或为空树空树;或是由一个根结根结点点加上两棵两
5、棵分别称为左子树左子树和右子树的、互不交的互不交的二叉树二叉树组成。ABCDEFGHK根结点左子树右子树EF第13页/共123页二叉树的五种基本形态:二叉树的五种基本形态:N空树空树只含根结点只含根结点NNNLRR右子树为空树右子树为空树L左子树为空树左子树为空树左右子树均不左右子树均不为空树为空树第14页/共123页二叉树二叉树的重要特性的重要特性第15页/共123页 性质性质 1:在二叉树的第 i 层上至多有2i-1 个结点。(i1)用归纳法用归纳法证明证明:归纳基归纳基:归纳假设:归纳假设:归纳证明:归纳证明:i=1 层时,只有一个根结点,2i-1=20=1;假设对所有的 j,1 j i
6、,命题成立;二叉树上每个结点至多有两棵子树,则第 i 层的结点数=2i-2 2=2i-1。第16页/共123页性质性质 2:深度为 k 的二叉树上至多含 2k-1 个结点(k1)证明:证明:基于上一条性质,深度为 k 的二叉树上的结点数至多为 20+21+2k-1=2k-1 第17页/共123页 性质性质 3:对任何一棵二叉树,若它含有n0 个叶子结点、n2 个度为 2 的结点,则必存在关系式:n0=n2+1证明:证明:设设 二叉树上结点总数 n=n0+n1+n2又又 二叉树上分支总数 b=n1+2n2而 b=n-1=n0+n1+n2-1由此,由此,n0=n2+1第18页/共123页两类两类特
7、殊特殊的二叉树:的二叉树:满二叉树满二叉树:指的是深度为k且含有2k-1个结点的二叉树。完全二叉树完全二叉树:树中所含的 n 个结点和满二叉树中编号为编号为 1 至至 n 的结点的结点一一对应。123456789 10 11 12 13 14 15abcdefghij第19页/共123页 性质性质 4:具有 n 个结点的完全二叉树的深度深度为 log2n +1证明:证明:设设 完全二叉树的深度为 k 则根据第二条性质得 2k-1 n 2k 即 k-1 log2 n n,则该结点无左孩子,否则,编号为 2i 的结点为其左孩子左孩子结点;(3)若 2i+1n,则该结点无右孩子结点,否则,编号为2i
8、+1 的结点为其右孩子右孩子结点。第21页/共123页6.3 二叉树的存储结构二叉树的存储结构二、二叉树的链式二、二叉树的链式 存储表示存储表示一、一、二叉树的顺序二叉树的顺序 存储表示存储表示第22页/共123页#define MAX_TREE_SIZE 100 /二叉树的最大结点数typedef TElemType SqBiTreeMAX_TREE_SIZE;/0号单元存储根结点SqBiTree bt;一、一、二叉树的顺序存储表示二叉树的顺序存储表示第23页/共123页例如例如:A B D C E F 0 1 2 3 4 5 6 7 8 9 10 11 12 13ABCDEF1401326
9、第24页/共123页二、二叉树的链式存储表示二、二叉树的链式存储表示1.1.二叉链表二叉链表2三叉链表三叉链表3 3双亲链表双亲链表4线索链表线索链表第25页/共123页ADEBCF rootlchild data rchild结点结构结点结构:1.1.二叉链表二叉链表第26页/共123页typedef struct BiTNode /结点结构结点结构 TElemType data;struct BiTNode *lchild,*rchild;/左右孩子指针 BiTNode,*BiTree;lchild data rchild结点结构结点结构:C 语言的类型描述如下语言的类型描述如下:第27页
10、/共123页rootADEBCF 2三叉链表三叉链表parent lchild data rchild结点结构结点结构:第28页/共123页 typedef struct TriTNode /结点结构结点结构 TElemType data;struct TriTNode *lchild,*rchild;/左右孩子指针 struct TriTNode *parent;/双亲指针 TriTNode,*TriTree;parent lchild data rchild结点结构结点结构:C 语言的类型描述如下语言的类型描述如下:第29页/共123页结点结构结点结构:3 3双亲链表双亲链表 data p
11、arentABDCEF0B41D42C03E14A-15F36LRTagLRRRRL根根第30页/共123页 typedef struct BPTNode /结点结构结点结构 TElemType data;int *parent;/指向双亲的指针 char LRTag;/左、右孩子标志域 BPTNode typedef struct BPTree/树结构树结构 BPTNode nodesMAX_TREE_SIZE;int num_node;/结点数目 int root;/根结点的位置 BPTree第31页/共123页 二叉树的主要基本操作二叉树的主要基本操作:(1)Init(bt)构造一棵空二
12、叉树、(2)Create(x,lbt,rbt)生成一棵以x为根结点,以二叉树lbt和rbt为左子树和右子树的二叉树(3)InsertL(x,Parent)将值为x的结点插入到二叉树中结点Parent的左孩子位置。如果结点Parent原来有左孩子结点,则将结点Parent原来的左孩子结点作为结点x的左孩子结点。(4)InsertR(x,Parent)将值为x的结点插入到二叉树中结点Parent的右孩子位置。如果结点Parent原来有右孩子结点,则将结点Parent原来的右孩子结点作为结点x的右孩子结点。第32页/共123页(5)DeleteL(bt,Parent)在二叉树bt中删除结点Paren
13、t的左子树(6)DeleteR(bt,Parent)在二叉树bt中删除结点Parent的右子树(7)Search(bt,x)在二叉树bt中查找数据元素x(8)Traverse(bt)按某种方式遍历二叉树第33页/共123页 实现算法(1)Init(bt)int Init(BiTree bt)if(bt=(BiTree)malloc(sizeof(BiTNode)=NULL)return 0;bt-Lchild=NULL;bt-rchild=NULL;return 1;第34页/共123页(2)Create(x,lbt,rbt)BiTree Create(x,lbt,rbt)BiTree p;i
14、f(bt=(BiTree)malloc(sizeof(BiTNode)=NULL)return NULL;p-data=x;p-lchild=lbt;p-rchild=rbt;return p;第35页/共123页(3)InsertL(x,Parent)BiTree InsertL(x,Parent)BiTree p;if(Parent=NULL)return NULL;if(bt=(BiTree)malloc(sizeof(BiTNode)=NULL)return NULL;p-data=x;p-lchild=NULL;p-rchild=NULL;if(Parent-lchild=NULL)
15、Parent-lchild=p;else p-lchild=Parent-lchild;Parent-lchild=p;第36页/共123页(5)DeleteL(bt,Parent)BiTree DeleteL(bt,Parent)BiTree p;if(Parent=NULL|Parent-lchild=NULL)return NULL;p=Parent-lchild;Parent-lchild=NULL;free(p);return bt;第37页/共123页6.4二叉树的遍历二叉树的遍历第38页/共123页一、问题的提出一、问题的提出二、先左后右的遍历算法二、先左后右的遍历算法三、算法的
16、递归描述三、算法的递归描述四、中序遍历算法的非递归描述四、中序遍历算法的非递归描述四四、遍历算法的应用举例遍历算法的应用举例第39页/共123页 顺着某一条搜索路径巡访巡访二叉树中的结点,使得每个结点均被访问一均被访问一次次,而且仅被访问一次仅被访问一次。一、问题的提出一、问题的提出“访问访问”的含义可以很广,如:输出结点的信息等。第40页/共123页 “遍历遍历”是任何类型均有的操作,对线性结构而言,只有一条搜索路径(因为每个结点均只有一个后继),故不需要另加讨论。而二叉树是非线性结构,每个结点有两个后继每个结点有两个后继,则存在如何遍历存在如何遍历即按什么样的搜索搜索路径路径进行进行遍历的
17、问题。第41页/共123页 对对“二叉树二叉树”而言,可以有三条搜索路径:而言,可以有三条搜索路径:1先上后下先上后下的按层次遍历;2先先左左(子树)后后右右(子树)的遍历;3先先右右(子树)后后左左(子树)的遍历。第42页/共123页二、先左后右的遍历算法二、先左后右的遍历算法先先(根)序的遍历算法中中(根)序的遍历算法后后(根)序的遍历算法根左子树右子树根根根根根第43页/共123页 若二叉树为空树,则空操作;否则,(1)访问根结点;(2)先序遍历左子树;(3)先序遍历右子树。先(根)序的遍历算法:先(根)序的遍历算法:第44页/共123页 若二叉树为空树,则空操作;否则,(1)中序遍历左
18、子树;(2)访问根结点;(3)中序遍历右子树。中(根)序的遍历算法:中(根)序的遍历算法:第45页/共123页 若二叉树为空树,则空操作;否则,(1)后序遍历左子树;(2)后序遍历右子树;(3)访问根结点。后(根)序的遍历算法:后(根)序的遍历算法:第46页/共123页ABCDEFGHK例如:先序序列:先序序列:中序序列:中序序列:后序序列:后序序列:A B C D E F G H KB D C A E H G K FD C B H K G F E A第47页/共123页三、算法的递归描述三、算法的递归描述void Preorder(BiTree T)/先序遍历二叉树 if(T)printf(
19、“%d”,T-data);/访问结点 Preorder(T-lchild,visit);/遍历左子树 Preorder(T-rchild,visit);/遍历右子树 第48页/共123页前序遍历算法的非递归描述void preorder(BiTree bt)BiTree*stackMaxsize,p;int top;if(bt!=NULL)top=1;stacktop=b;/根结点入栈 while(top0)/栈不为空时循环 p=stacktop-;/退栈并访问该结点 printf(“%d”,p-data);if(p-rchild!=NULL)/右孩子入栈 stacktop=p-rchild;
20、top+;if(p-lchild!=NULL)/左孩子入栈 stacktop=p-lchild;top+;/while /if第49页/共123页中序遍历算法的非递归描述中序遍历算法的非递归描述BiTNode*GoFarLeft(BiTree T,Stack*S)if(!T)return NULL;while(T-lchild)Push(S,T);T=T-lchild;return T;第50页/共123页void Inorder(BiTree T,void(*visit)(TelemType&e)Stack*S;t=GoFarLeft(T,S);/找到最左下的结点 while(t)visit
21、(t-data);if(t-rchild)else if(!StackEmpty(S)t=Pop(S);/退栈 else t=NULL;/栈空表明遍历结束 /while t=GoFarLeft(t-rchild,S);第51页/共123页四四、遍历算法的应用举例遍历算法的应用举例2、统计二叉树中叶子结点的个数、统计二叉树中叶子结点的个数3、求二叉树的深度、求二叉树的深度(后序遍历后序遍历)4 4、建立二叉树的存储结构、建立二叉树的存储结构1、查询二叉树中某个结点、查询二叉树中某个结点第52页/共123页1.在二叉树不空的前提下,和根结点的元素进行比较,若相等,则找到返回 TRUE;2.否则在左
22、子树中进行查找,若找到,则返回 TRUE;3.否则继续在右子树中进行查找,若找到,则返回 TRUE,否则返回 FALSE;第53页/共123页Status Preorder(BiTree T,ElemType x)/若二叉树中存在和若二叉树中存在和 x 相同的元素,则相同的元素,则 p p 指向该结点并返回指向该结点并返回 OK,/否则返回否则返回 FALSE if(T)if(T-data=x)p=T;return OK,/if else return FALSE;else if(Preorder(T-lchild,x)return OK;else return(Preorder(T-rchi
23、ld,x);/else第54页/共123页2、统计二叉树中叶子结点的个数、统计二叉树中叶子结点的个数int count=0;int CountLeaf(BiTree T,count)if(T)if(!T-lchild)&(!T-rchild)count+;/对叶子结点计数 CountLeaf(T-lchild,count);CountLeaf(T-rchild,count);return count;else return 0;/CountLeaf第55页/共123页3、求二叉树的深度、求二叉树的深度(后序遍历后序遍历)算法基本思想算法基本思想:从二叉树深度的定义可知,二叉树的深度应为其左、右
24、子树深度的最大值加二叉树的深度应为其左、右子树深度的最大值加1 1。由此,需先分别求得左、右子树的深度,需先分别求得左、右子树的深度,算法中“访问结点”的操作为:求得左、求得左、右子树深度的最大值,然后加右子树深度的最大值,然后加 1 1。首先分析二叉树的深度二叉树的深度和它的左左、右子树深度右子树深度之间的关系。第56页/共123页int Depth(BiTree T)/返回二叉树的深度 if(!T)depthval=0;else depthLeft=Depth(T-lchild);depthRight=Depth(T-rchild);depthval=1+(depthLeft depthR
25、ight?depthLeft:depthRight);return depthval;第57页/共123页5 5、建立二叉树的存储结、建立二叉树的存储结构构不同的定义方法相应有不同的存储结构的建立算法第58页/共123页 以字符串的形式以字符串的形式 “根根 左子树左子树 右子树右子树”定义一棵二叉树定义一棵二叉树例如例如:以空白字符“”表示ABCDAB C D 空树空树只含一个根结点的二叉树只含一个根结点的二叉树A以字符串“A ”表示以下列字符串表示第59页/共123页int CreateBiTree(BiTree&T)scanf(&ch);if(ch=)T=NULL;else if(!(T
26、=new BiTNode)exit(OVERFLOW);T-data=ch;/生成根结点 CreateBiTree(T-lchild);/构造左子树 CreateBiTree(T-rchild);/构造右子树 return 1;/CreateBiTree第60页/共123页A B C D A BCD上页算法执行过程举例如下:ATBCDscanf(&ch);if(ch=)T=NULL;else if(!(T=new BiTNode)exit(OVERFLOW);T-data=ch;CreateBiTree(T-lchild);CreateBiTree(T-rchild);第61页/共123页 仅
27、知二叉树的先序序列“abcdefg”能否唯一确定一棵二叉树?由二叉树的先序和中序序列建树由二叉树的先序和中序序列建树 如果同时已知二叉树的中序序列“cbdaegf”,则会如何?二叉树的先序序列二叉树的中序序列左子树左子树右子树右子树根根第62页/共123页a b c d e f gc b d a e g f例如例如:aab bccddeeffggabcdefg先序序列中序序列第63页/共123页6.5线索二叉树线索二叉树 何谓线索二叉树?何谓线索二叉树?线索链表的遍历算法线索链表的遍历算法第64页/共123页一、何谓线索二叉树?何谓线索二叉树?遍历二叉树的结果是,求得结点的一个线性序列。ABC
28、DEFGHK例如:先序先序序列:A B C D E F G H K中序中序序列:B D C A H G K F E后序后序序列:D C B H K G F E A第65页/共123页指向该线性序列中的“前驱”和 “后继”的指针指针,称作“线线索索”与其相应的二叉树,称作“线索二叉树线索二叉树”包含“线索”的存储结构,称作“线索线索链表链表”A B C D E F G H K D C B E 第66页/共123页对对线索链表线索链表中结点的约定:中结点的约定:在二叉链表的结点中增加两个标志域增加两个标志域,并作如下规定:若该结点的左子树不空,若该结点的左子树不空,则Lchild域的指针指向其左子
29、树,且左标志域的值为“0”;否则,Lchild域的指针指向其“前驱”,且左标志的值为“1”。第67页/共123页若该结点的右子树不空,若该结点的右子树不空,则rchild域的指针指向其右子树,且右标志域的值为“0”;否则,rchild域的指针指向其“后继”,且右标志的值为“1”。如此定义的二叉树的存储结构称作如此定义的二叉树的存储结构称作“线索链表线索链表”第68页/共123页typedef struct BiThrNod TElemType data;struct BiThrNode *lchild,*rchild;/左右指针 PointerThr LTag,RTag;/左右标志 BiThr
30、Node,*BiThrTree;线索链表的类型描述:typedef enum Link,Thread PointerThr;/Link=0:指针,Thread=1:线索第69页/共123页二、线索链表的遍历算法二、线索链表的遍历算法:for(p=firstNode(T);p;p=Succ(p)Visit(p);由于在线索链表中添加了遍历中得到的“前驱”和“后继”的信息,从而简化了遍历的算法。第70页/共123页例如例如:对中序线索化链表的遍历算法对中序线索化链表的遍历算法 中序遍历的第一个结点中序遍历的第一个结点?在中序线索化链表中结点的后继在中序线索化链表中结点的后继?左子树上处于“最左下最
31、左下”(没有左子树)的结点若若无右子树,则为则为后继线索后继线索所指结点否则为否则为对其右子树右子树进行中序遍历遍历时访问的第一个结点第一个结点第71页/共123页void InOrderTraverse_Thr(BiThrTree T)p=T-lchild;/p指向根结点 while(p!=T)/空树或遍历结束时,p=T while(p-LTag=Link)p=p-lchild;visit(p-data)/第一个结点 while(p-RTag=Thread&p-rchild!=T)p=p-rchild;visit(p-data)/访问后继结点 p=p-rchild;/p进至其右子树根 /In
32、OrderTraverse_Thr第72页/共123页 6.6 树和森林 的表示方法第73页/共123页树的三种存储结构树的三种存储结构一、一、双亲表示法双亲表示法二、二、孩子链表表示法孩子链表表示法三、三、树的二叉链表树的二叉链表(孩子孩子-兄弟)兄弟)存储表示法存储表示法第74页/共123页ABCDEFGr=0n=70 A -11 B 02 C 03 D 04 E 2 5 F 26 G 5data parent一、双亲表示法一、双亲表示法:第75页/共123页 typedef struct PTNode Elem data;int parent;/双亲位置域 PTNode;data par
33、ent#define MAX_TREE_SIZE 100结点结构结点结构:C语言的类型描述语言的类型描述:第76页/共123页typedef struct PTNode nodes MAX_TREE_SIZE;int r,n;/根结点的位置和结点个数 PTree;树结构树结构:第77页/共123页r=0n=7 data firstchildABCDEFG0 A -11 B 02 C 03 D 04 E 25 F 26 G 464 5 1 2 3二、孩子链表表示法二、孩子链表表示法:-1 0 0 0 2 2 4第78页/共123页typedef struct CTNode int child;s
34、truct CTNode*nextchild;*ChildPtr;孩子结点结构孩子结点结构:child nextchildC语言的类型描述语言的类型描述:第79页/共123页 typedef struct Elem data;ChildPtr firstchild;/孩子链的头指针 CTBox;双亲结点结构双亲结点结构 data firstchild第80页/共123页typedef struct CTBox nodesMAX_TREE_SIZE;int n,r;/结点数和根结点的位置 CTree;树结构树结构:第81页/共123页ABCDEFGroot AB C E D F G AB C E
35、 D F G 三、树的二叉链表三、树的二叉链表(孩子孩子-兄弟)存储表示法兄弟)存储表示法root第82页/共123页typedef struct CSNode Elem data;struct CSNode *firstchild,*nextsibling;CSNode,*CSTree;C语言的类型描述语言的类型描述:结点结构结点结构:firstchild data nextsibling第83页/共123页 森林和二叉树的对应关系森林和二叉树的对应关系设设森林森林 F=(T1,T2,Tn);T1=(root,t11,t12,t1m);二叉树二叉树 B=(LBT,Node(root),RBT
36、);第84页/共123页由森林转换成二叉树由森林转换成二叉树的转换规则为:若 F=,则 B=;由 ROOT(T1)对应得到Node(root);否则,由(t11,t12,t1m)对应得到 LBT;由(T2,T3,Tn)对应得到 RBT。第85页/共123页由二叉树转换为森林由二叉树转换为森林的转换规则为:由LBT 对应得到(t11,t12,,t1m);若 B=,则 F=;否则,由 Node(root)对应得到 ROOT(T1);由RBT 对应得到(T2,T3,Tn)。第86页/共123页T1T11,T12,T1mT2,TnLBTRBTroot第87页/共123页 由此,树和森林的各种操作均可与
37、二叉树的各种操作相对应。应当注意的是,应当注意的是,和树对应的二叉树,其左、右子树的概念已改变为:左是孩子,右是兄弟左是孩子,右是兄弟第88页/共123页6.7树和森林的遍历树和森林的遍历第89页/共123页一、树的遍历一、树的遍历二、森林的遍历二、森林的遍历三、树的遍历的应用三、树的遍历的应用第90页/共123页树的遍历可有树的遍历可有3条搜索路径条搜索路径:按层次遍历按层次遍历:先根先根(次序次序)遍历遍历:后根后根(次序次序)遍历遍历:若树不空,则先访问根结点,然后依次先根遍历各棵子树。若树不空,则先访问根结点,然后依次先根遍历各棵子树。若树不空,则先依次后根遍历各棵子树,然后访问根结点
38、。若树不空,则先依次后根遍历各棵子树,然后访问根结点。若树不空,则自上而下自左至右访问树中每个结点。若树不空,则自上而下自左至右访问树中每个结点。第91页/共123页 层次遍历时顶层次遍历时顶点的访问次序:点的访问次序:A B C DE F G H I J K 先根遍历时顶点先根遍历时顶点的访问次序:的访问次序:A B E F C D G H I J K 后根遍历时顶点后根遍历时顶点的访问次序:的访问次序:E F B C I J K H G D AA B C D E F G H I J K第92页/共123页 B C DE F G H I J K1。森林中第一棵树的根结点;2。森林中第一棵树的
39、子树森林;3。森林中其它树构成的森林。可以分解成三部分:森林森林第93页/共123页 若森林不空,则访问访问森林中第一棵树的根结点;先序遍历先序遍历森林中第一棵树的子树森林;先序遍历先序遍历森林中(除第一棵树之外)其 余树构成的森林。先序遍历先序遍历森林的遍历森林的遍历即:依次从左至右依次从左至右对森林中的每一棵树树进行先根遍历先根遍历。第94页/共123页 中序遍历中序遍历 若森林不空,则中序遍历中序遍历森林中第一棵树的子树森林;访问访问森林中第一棵树的根结点;中序遍历中序遍历森林中(除第一棵树之外)其 余树构成的森林。即:依次从左至右依次从左至右对森林中的每一棵树树进行后根遍历后根遍历。第
40、95页/共123页 树的遍历和二叉树遍历树的遍历和二叉树遍历的对应关系的对应关系?先根遍历先根遍历后根遍历后根遍历树树二叉树二叉树森林森林先序遍历先序遍历先序遍历先序遍历中序遍历中序遍历中序遍历中序遍历第96页/共123页设树的存储结构为孩子兄弟链表设树的存储结构为孩子兄弟链表typedef struct CSNode Elem data;struct CSNode*firstchild,*nextsibling;CSNode,*CSTree;求树的深度求树的深度第97页/共123页Int Depth(CSTree T)If(T=NULL)return 0;ElseD1=Depth(T-fir
41、stchild);D2=Depth(T-nextsibling);Return Maxd1+1,d2第98页/共123页int TreeDepth(CTree T)/T 是树的孩子链表存储结构,/返回该树的深度 if(T.n=0)return 0;else return Depth(T,T.r);/TreeDepth一、求树的深度的算法:一、求树的深度的算法:第99页/共123页int Depth(CTree T,int root)max=0;p=T.nodesroot.firstchild;while(p)h=Depth(T,p-child);if(h max)max=h;p=p-nextc
42、hild;/while return max+1;第100页/共123页6.8 哈哈 夫夫 曼曼 树树 与与 哈哈 夫夫 曼曼 编编 码码 最优树的定义最优树的定义 如何构造最优树如何构造最优树 前缀编码前缀编码 第101页/共123页 一、最优树的定义一、最优树的定义树的路径长度树的路径长度定义为:树中每个结点的路径长度之和。结点的路径长度结点的路径长度定义为:从根结点到该结点的路径上 分支的数目。第102页/共123页 树的带权路径长度树的带权路径长度定义为:树中所有叶子结点的带权路径长度结点的带权路径长度之和 WPL(T)=wklk(对所有叶子结点)在所有含 n 个叶子结点、并带相同权值
43、的二叉树中,必存在一棵其带权路径带权路径长度取最小值长度取最小值的树,称为“最优树最优树”。例如:第103页/共123页27 9 75492WPL(T)=72+52+23+43+92 =60WPL(T)=74+94+53+42+21 =89 54第104页/共123页最佳判定树最佳判定树考试成绩分布表考试成绩分布表 第105页/共123页判定树判定树不及格不及格不及格不及格及格及格及格及格中中中中良良良良优优优优60?70?80?90?0.100.150.250.350.15 WPL=0.10*1+0.15*2+0.25*3+0.35*4+0.15*4 =3.15 第106页/共123页最佳判定树最佳判定树不及格不及格不及格不及格及格及格及格及格中中中中良良良良优优优优60?70?80?90?0.100.150.250.350.15 data);exit(1);else getPreSeq(T-lchild,int k);getPreSeq(T-rchild,int k);第122页/共123页感谢您的观看。第123页/共123页