《树的类型定义学习教案.pptx》由会员分享,可在线阅读,更多相关《树的类型定义学习教案.pptx(126页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、会计学 1树的类型定义第一页,共126页。6.1 树的类型定义6.2 二叉树的类型定义6.3 二叉树的存储(cn ch)结构6.4 二叉树的遍历(bin l)6.5 线索(xin su)二叉树6.6 树和森林的表示方法6.7 树和森林的遍历6.8 哈夫曼树与哈夫曼编码第1页/共126页第二页,共126页。6.1 树的类型定义第2页/共126页第三页,共126页。数据(shj)对象 D:D是具有相同特性的数据元素(yun s)的集合。若D为空集,则称为空树;否则:(1)在D中存在唯一的称为根的数据元素root,(2)当n1时,其余结点可分为(fn wi)m(m0)个互 不相交的有限集T1,T2,
2、Tm,其中每一 棵子集本身又是一棵符合本定义的树,称为根root的子树。数据关系 R:第3页/共126页第四页,共126页。基本操作:查 找 类 插 入 类删 除 类第4页/共126页第五页,共126页。Root(T)/求树的根结点(ji din)Value(T,cur_e)/求当前结点(ji din)的元素值 Parent(T,cur_e)/求当前结点(ji din)的双亲结点(ji din)LeftChild(T,cur_e)/求当前结点的最左孩子 RightSibling(T,cur_e)/求当前结点的右兄弟TreeEmpty(T)/判定树是否为空树 TreeDepth(T)/求树的深度
3、TraverseTree(T,Visit()/遍历查找类:第5页/共126页第六页,共126页。InitTree(&T)/初始化置空树 CreateTree(&T,definition)/按定义(dngy)构造树Assign(T,cur_e,value)/给当前(dngqin)结点赋值InsertChild(&T,&p,i,c)/将以c为根的树插入(ch r)为结点p的第i棵子树插入类:第6页/共126页第七页,共126页。ClearTree(&T)/将树清空(qn kn)DestroyTree(&T)/销毁(xiohu)树的结构DeleteChild(&T,&p,i)/删除(shnch)结点
4、p的第i棵子树删除类:第7页/共126页第八页,共126页。ABC DE F G H I JM K L树的表示法:(1)树形表示法第8页/共126页第九页,共126页。10A(B(E,F(K,L),C(G),D(H,I,J(M)T1T3T2树根(sh n)(2)广义(gungy)表表示法(用于输入)(3)嵌套集合(jh)表示法(4)凹入表示法(用于打印输出)第9页/共126页第十页,共126页。对比树型结构(jigu)和线性结构(jigu)的结构(jigu)特点第10页/共126页第十一页,共126页。线性结构(jigu)树型结构(jigu)第一个数据(shj)元素(无前驱)根结点(无前驱)最
5、后一个数据元素(无后继)多个叶子结点(无后继)其它数据元素(一个前驱、一个后继)其它数据元素(一个前驱、多个后继)第11页/共126页第十二页,共126页。基 本 术 语第12页/共126页第十三页,共126页。结点(ji din):结点(ji din)的度:树的度:叶子(y zi)结点:分支结点:数据元素+若干指向子树的分支分支的个数树中所有结点的度的最大值度为零的结点度大于零的结点DH IJM第13页/共126页第十四页,共126页。(从根到结点(ji din)的)路径:孩子结点(ji din)、双亲结点(ji din)、兄弟结点(ji din)、堂兄弟祖先结点(ji din)、子孙结点(
6、ji din)结点(ji din)的层次:树的深度:由从根到该结点所经分支和结点构成ABCDE F G H I JM K L假设根结点的层次为1,第l 层的结点的子树根结点的层次为l+1树中叶子结点所在的最大层次第14页/共126页第十五页,共126页。()有确定的根;()树根(sh n)和子树根(sh n)之间为有向关系。有向树:有序树:子树之间存在确定(qudng)的次序关系。无序(w x)树:子树之间不存在确定的次序关系。第15页/共126页第十六页,共126页。任何一棵非空树是一个二元组 Tree=(root,F)其中(qzhng):root 被称为根结点,F 被称为子树森林森林(sn
7、ln):是m(m0)棵互不相交(xingjio)的树的集合ArootB C DE F G HIJM KLF第16页/共126页第十七页,共126页。6.2 二叉树的类型定义第17页/共126页第十八页,共126页。二叉树或为空树;或是由一个根结点加上两棵分别(fnbi)称为左子树和右子树的、互不交的二叉树组成。ABCDEFGH K根结点(ji din)左子树右子树第18页/共126页第十九页,共126页。NN N NLR R L空树只含根结点(ji din)右子树为空树左子树为空树左右(zuyu)子树均不为空树二叉树的五种(w zh n)基本形态:第19页/共126页第二十页,共126页。查
8、找 类插 入 类删 除 类 二叉树的主要 二叉树的主要(zh(zh yo)yo)基本操作:基本操作:第20页/共126页第二十一页,共126页。Root(T);Value(T,e);Parent(T,e);LeftChild(T,e);RightChild(T,e);LeftSibling(T,e);RightSibling(T,e);BiTreeEmpty(T);BiTreeDepth(T);PreOrderTraverse(T,Visit();InOrderTraverse(T,Visit();PostOrderTraverse(T,Visit();LevelOrderTraverse(T
9、,Visit();查 找 类第21页/共126页第二十二页,共126页。InitBiTree(&T);Assign(T,&e,value);CreateBiTree(&T,definition);InsertChild(T,p,LR,c);插 入 类第22页/共126页第二十三页,共126页。ClearBiTree(&T);DestroyBiTree(&T);DeleteChild(T,p,LR);删 除 类第23页/共126页第二十四页,共126页。二叉树的重要(zhngyo)特性第24页/共126页第二十五页,共126页。性质1:在二叉树的第 i 层上至多(zhdu)有2i-1 个结点。(
10、i1)用归纳法证明用归纳法证明(zhngmng)(zhngmng):归纳基:归纳基:归纳假设:归纳假设:归纳证明归纳证明(zhngmng)(zhngmng):i=1 层时,只有(zhyu)一个根结点,2i-1=20=1;假设对所有的 j,1 j i,命题成立;二叉树上每个结点至多有两棵子树,则第 i 层的结点数=2i-2 2=2i-1。第25页/共126页第二十六页,共126页。性质(xngzh)2:深度为 k 的二叉树上至多含 2k-1 个结点(k1)证明(zhngmng):基于上一条性质(xngzh),深度为 k 的二叉树上的结点数至多为 20+21+2k-1=2k-1 第26页/共126
11、页第二十七页,共126页。性质 3:对任何一棵二叉树,若它含有(hn y u)n0 个叶子结点、n2 个度为 2 的结点,则必存在关系式:n0=n2+1 证明(zhngmng):设 二叉树上结点(ji din)总数 n=n0+n1+n2又 二叉树上分支总数 b=n1+2n2 而 b=n-1=n0+n1+n2-1由此,n0=n2+1第27页/共126页第二十八页,共126页。29课堂(ktng)练习题 树T有n个结点且结点的度均为k或者(huzh)0,则树中的叶子结点总数为_。(广东工业大学05年考研试题)解:设 树上结点总数(zngsh)n=n0+nk 又树上分支总数(zngsh)b=k*nk
12、 而 b=n-1 由此,n0=n-(n-1)/kn-(n-1)/k第28页/共126页第二十九页,共126页。满二叉树:深度为k且含有(hn yu)2k-1个结点的二叉树。完全(wnqun)二叉树:树中所含的 n 个结点和满二叉树中编号为 1 至 n 的结点一一对应。12 34 5 6 78 9 10 11 12 1314 15abcd e f ghi j两类特殊(tsh)的二叉树:第29页/共126页第三十页,共126页。证明(zhngmng):设 完全二叉树的深度为 k 则根据第二条性质得 2k-1 n 2k 即 k-1 log2 n k 因为 k 只能是整数(zhngsh),因此,k=l
13、og2n+1性质(xngzh)4:具有 n 个结点的完全二叉树的深度为 log2n+1第30页/共126页第三十一页,共126页。若对含 n 个结点的完全二叉树从上到下且从左至右进行 1 至 n 的编号,则对完全二叉树中任意(rny)一个编号为 i 的结点:(1)若 i=1,则该结点是二叉树的根,无双亲,否则,编号为 i/2 的结点为其双亲结点;(2)若 2in,则该结点无左孩子,否则,编号为 2i 的结点为其左孩子结点;(3)若 2i+1n,则该结点无右孩子结点,否则,编号为2i+1 的结点为其右孩子结点。性质(xngzh)5:12 34 5 6 78 910 11 12 13 14 15第
14、31页/共126页第三十二页,共126页。33练习题 已知一棵完全(wnqun)二叉树共有748个结点,则该树中有_个叶子结点。解:根据二叉树性质4,可知该完全二叉树高度为:H log2n+1=log2748+1=10由性质2,前9层共有结点数:29-1511第10层叶子(y zi)数:748-511 237由性质1,第9层结点数:29-1256第9层的双亲结点数:237/2 1119第9层叶子(y zi)数:256-119 137该完全二叉树叶子(y zi)结点总数:237137374374第32页/共126页第三十三页,共126页。二、二叉树的链式 存储(cn ch)表示一、二叉树的顺序(
15、shnx)存储表示6.3 二叉树的存储(cn ch)结构第33页/共126页第三十四页,共126页。#define MAX_TREE_SIZE 100/二叉树的最大结点数typedef TElemType SqBiTreeMAX_TREE_SIZE;/0号单元(dnyun)存储根结点SqBiTree bt;一、二叉树的顺序存储表示(bi osh)第34页/共126页第三十五页,共126页。例如(lr):ABCDEF A B D 0 C 0 E 0 0 0 0 0 0 F 0 1 2 3 4 5 6 7 8 9 10 11 12 1314013263 578 9 10 11 12第35页/共12
16、6页第三十六页,共126页。1.二叉链表2三叉链表3双亲(shungqn)链表4线索(xin su)链表二、二叉树的链式存储(cn ch)表示第36页/共126页第三十七页,共126页。ADEBCF rootlchild data rchild结点(ji din)结构:1.二叉链表第37页/共126页第三十八页,共126页。typedef struct BiTNode/结点结构 TElemType data;struct BiTNode*lchild,*rchild;/左右(zuyu)孩子指针 BiTNode,*BiTree;lchild data rchild结点(ji din)结构:C 语
17、言的类型描述(mio sh)如下:第38页/共126页第三十九页,共126页。ADEBCF rootparent lchild data rchild结点(ji din)结构:2三叉链表第39页/共126页第四十页,共126页。typedef struct TriTNode/结点(ji din)结构 TElemType data;struct TriTNode*lchild,*rchild;/左右孩子指针 struct TriTNode*parent;/双亲指针 TriTNode,*TriTree;parent lchild data rchild结点(ji din)结构:C 语言的类型描述(
18、mio sh)如下:第40页/共126页第四十一页,共126页。0123456 data parent结点(ji din)结构:LRTagLRRRL3双亲(shungqn)链表ABCDEF第41页/共126页第四十二页,共126页。typedef struct BPTNode/结点结构(jigu)TElemType data;int*parent;/指向双亲的指针 char LRTag;/左、右孩子标志域 BPTNode typedef struct BPTree/树结构(jigu)BPTNode nodesMAX_TREE_SIZE;int num_node;/结点数目 int root;/
19、根结点的位置 BPTree第42页/共126页第四十三页,共126页。6.4二叉树的遍历(bin l)第43页/共126页第四十四页,共126页。顺着某一条搜索路径(ljng)巡访二叉树中的结点,使得每个结点均被访问一次,而且仅被访问一次。一、问题(wnt)的提出“访问”的含义可以很广,如:输出(shch)结点的信息,计算结点个数等。第44页/共126页第四十五页,共126页。“遍历”是任何(rnh)类型均有的操作,对线性结构而言,只有一条搜索路径(因为每个结点均只有一个后继),故不需要另加讨论。而二叉树是非线性结构,每个结点有两个后继,则存在如何遍历即按什么样的搜索路径遍历的问题。第45页/
20、共126页第四十六页,共126页。对“二叉树”而言,可以有三条搜索(su su)路径:1先上后下的按层次(cngc)遍历;2先左(子树)后右(子树)的遍历;3先右(子树)后左(子树)的遍历。第46页/共126页第四十七页,共126页。二、先左后右的遍历(bin l)算法先(根)序的遍历(bin l)算法中(根)序的遍历(bin l)算法后(根)序的遍历算法第47页/共126页第四十八页,共126页。若二叉树为空树,则空操作;否则,(1)访问根结点(ji din);(2)先序遍历左子树;(3)先序遍历右子树。先(根)序的遍历(bin l)算法:第48页/共126页第四十九页,共126页。若二叉树
21、为空树,则空操作;否则(fuz),(1)中序遍历左子树;(2)访问根结点;(3)中序遍历右子树。中(根)序的遍历(bin l)算法:第49页/共126页第五十页,共126页。若二叉树为空树,则空操作;否则,(1)后序遍历(bin l)左子树;(2)后序遍历(bin l)右子树;(3)访问根结点。后(根)序的遍历(bin l)算法:第50页/共126页第五十一页,共126页。void Preorder(BiTree T,void(*visit)(TElemType&e)/先序遍历二叉树 if(T)visit(T-data);/访问(fngwn)结点 Preorder(T-lchild,visit
22、);/遍历左子树 Preorder(T-rchild,visit);/遍历右子树 三、算法(sun f)的递归描述第51页/共126页第五十二页,共126页。四、中序遍历(bin l)的递归与非递归描述 void Inorder(BiTree T,void(*visit)(TElemType&e)/中序递归遍历二叉树 if(T)Preorder(T-lchild,visit);/遍历左子树 visit(T-data);/访问(fngwn)结点 Preorder(T-rchild,visit);/遍历右子树 第52页/共126页第五十三页,共126页。void Inorder_I(BiTree
23、T,void(*visit)(TElemType&e)/中序非递归遍历二叉树 InitStack(S);Push(S,T);/根指针进栈 While(!StackEmpty(S)While(GetTop(S,p)&p)Push(S,p-lchild);Pop(S,p);/空指针退栈 if(!StackEmpty(S)/访问(fngwn)结点,向右一步 Pop(S,p);if(!Visit(p-data)return ERROR;Push(S,p-rchild);/if/while Return OK;第53页/共126页第五十四页,共126页。55课堂练习 请说出下图二叉树的先序、中序和后序遍
24、历(bin l)次序?ab cd e f gh i ja,b,d,h,i,e,j,c,f,g a,b,d,h,i,e,j,c,f,gh,d,i,b,j,e,a,f,c,g h,d,i,b,j,e,a,f,c,gh,i,d,j,e,b,f,g,c,a h,i,d,j,e,b,f,g,c,a先序:先序:中序:中序:后序 后序(hu(hu x)x):第54页/共126页第五十五页,共126页。1、统计二叉树中叶子(y zi)结点的个数(先序遍历)2、求二叉树的深度(shnd)(后序遍历)3、建立(jinl)二叉树的存储结构五、二叉树遍历算法应用举例6.4 二叉树的遍历第55页/共126页第五十六页,
25、共126页。算法(sun f)基本思想:先序(或中序或后序)遍历二叉树,在遍历过程中查找叶子结点,并计数。由此,需在遍历算法中增添一个“计数”的参数,并将算法中“访问(fngwn)结点”的操作改为:若是叶子,则计数器增1。1、统计二叉树中叶子(y zi)结点的个数(先序遍历)第56页/共126页第五十七页,共126页。void CountLeaf(BiTree T,int&count)if(T)if(!T-lchild)&(!T-rchild)count+;/对叶子(y zi)结点计数 CountLeaf(T-lchild,count);CountLeaf(T-rchild,count);/i
26、f/CountLeaf第57页/共126页第五十八页,共126页。算法(sun f)基本思想:从二叉树深度的定义可知,二叉树的深度应为其左、右子树深度的最大值加1。由此,需先分别求得左、右子树的深度,算法中“访问(fngwn)结点”的操作为:求得左、右子树深度的最大值,然后加 1。首先(shuxin)分析二叉树的深度和它的左、右子树深度之间的关系。2、求二叉树的深度(后序遍历)第58页/共126页第五十九页,共126页。int Depth(BiTree T)/返回(fnhu)二叉树的深度 if(!T)depthval=0;else depthLeft=Depth(T-lchild);depth
27、Right=Depth(T-rchild);depthval=1+(depthLeft depthRight?depthLeft:depthRight);return depthval;第59页/共126页第六十页,共126页。3、建立二叉树的存储(cn ch)结构不同的存储结构有不同的建立算法(sun f),下面以二叉链表存储结构为例说明:第60页/共126页第六十一页,共126页。以字符串的形式(xngsh)输入 根 左子树 右子树用先序次序定义一棵二叉树例如(lr):ABCD以空白字符(z f)“”表示A(B(,C(,),D(,)空树只含一个根结点的二叉树A以字符串“A”表示以下列字符串
28、表示第61页/共126页第六十二页,共126页。Status CreateBiTree(BiTree&T)scanf(&ch);if(ch=)T=NULL;else if(!(T=(BiTNode*)malloc(sizeof(BiTNode)exit(OVERFLOW);T-data=ch;/生成根结点(ji din)CreateBiTree(T-lchild);/构造左子树 CreateBiTree(T-rchild);/构造右子树 return OK;/CreateBiTree第62页/共126页第六十三页,共126页。A B C D AB C D上页算法(sun f)执行过程举例如下:
29、ATBCD 第63页/共126页第六十四页,共126页。仅知二叉树的先序序列“abcdefg”不能唯一(wi y)确定一棵二叉树,为什么?如果(rgu)同时已知二叉树的中序序列“cbdaegf”,则会如何?二叉树的先序序列(xli)二叉树的中序序列左子树左子树右子树右子树根根第64页/共126页第六十五页,共126页。a b c d e f gc b d a e g f例如(lr):aab bccddeeffggabc defg先序序列(xli)中序序列(xli)第65页/共126页第六十六页,共126页。67练习题已知一个二叉树的先序遍历次序已知一个二叉树的先序遍历次序(cx)(cx)是:是
30、:88,55,11,33,22,44,66,77,1010,99,11 11 中序遍历次序中序遍历次序(cx)(cx)是:是:11,22,33,44,55,66,77,88,99,1010,1111 请画出该二叉树的树形逻辑图示,并求请画出该二叉树的树形逻辑图示,并求出其后序遍历次序出其后序遍历次序(cx)(cx)。第66页/共126页第六十七页,共126页。68解:后序遍历后序遍历(bin l)(bin l)次序:次序:22,44,33,11,77,66,55,99,1111,1010,88第67页/共126页第六十八页,共126页。6.5线索(xin su)二叉树uu 何谓(hwi)线索二
31、叉树?uu 线索链表的遍历算法uu 如何建立线索链表?第68页/共126页第六十九页,共126页。遍历(bin l)二叉树的结果是:求得结点的一个线性序列。ABCDEFGH K例如(lr):先序序列(xli):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一、何谓线索二叉树?第69页/共126页第七十页,共126页。指向该线性序列(xli)中的“前驱”和“后继”的指针,称作“线索”与其相应(xingyng)的二叉树,称作“线索二叉树”包含“线索(xin su)”的存储结构,称作“线索(xin su)链表”A B C D
32、 E F G H K D C B E 第70页/共126页第七十一页,共126页。对线索(xin su)链表中结点的约定:在二叉链表的结点中增加两个(lin)标志域,并作如下规定:若该结点的左子树不空,则Lchild域的指针指向其左子树,且左标志(biozh)域的值为“指针 Link”;否则,Lchild域的指针指向其“前驱”,且左标志(biozh)的值为“线索 Thread”。第71页/共126页第七十二页,共126页。若该结点的右子树不空,则rchild域的指针指向其右子树,且右标志域的值为“指针 Link”;否则,rchild域的指针指向其“后继(huj)”,且右标志的值为“线索 Thr
33、ead”。如此定义的二叉树的存储结构(jigu)称作“线索链表”第72页/共126页第七十三页,共126页。typedef struct BiThrNod TElemType data;struct BiThrNode*lchild,*rchild;/左右指针(zhzhn)PointerThr LTag,RTag;/左右标志 BiThrNode,*BiThrTree;线索链表的类型(lixng)描述:typedef enum Link,Thread PointerThr;/Link=0:指针(zhzhn),Thread=1:线索lchild L T ag data R T ag r child
34、第73页/共126页第七十四页,共126页。由于在线索链表中添加了遍历(bin l)中得到的“前驱”和“后继”的信息,从而简化了遍历(bin l)的算法。二、线索(xin su)链表的遍历算法:第74页/共126页第七十五页,共126页。例如:对中序线索化链表的遍历(bin l)算法 中序遍历(bin l)的第一个结点?在中序线索(xin su)化链表中结点的后继?左子树上处于“最左下”(没有左子树)的结点若无右子树,则为后继线索所指结点否则为对其右子树进行中序遍历时访问的第一个结点第75页/共126页第七十六页,共126页。void InOrderTraverse_Thr(BiThrTree
35、 T,void(*Visit)(TElemType e)p=T-lchild;/p指向根结点 while(p!=T)/空树或遍历结束时,p=T while(p-LTag=Link)p=p-lchild;/第一个结点 if(!Visit(p-data)return ERROR;while(p-RTag=Thread&p-rchild!=T)p=p-rchild;Visit(p-data);/访问后继(huj)结点 p=p-rchild;/p进至其右子树根/InOrderTraverse_Thr第76页/共126页第七十七页,共126页。在中序遍历过程中修改结点的左、右指针域,以保存当前访问结点的
36、“前驱”和“后继”信息(xnx)。遍历过程中,附设指针pre,并始终保持指针pre指向当前访问的、指针p所指结点的前驱。三、如何(rh)建立线索链表?第77页/共126页第七十八页,共126页。void InThreading(BiThrTree p)if(p)/对以p为根的非空二叉树进行线索化 InThreading(p-lchild);/左子树线索化 if(!p-lchild)/建前驱(qinq)线索 p-LTag=Thread;p-lchild=pre;if(!pre-rchild)/建后继线索 pre-RTag=Thread;pre-rchild=p;pre=p;/保持 pre 指向
37、p 的前驱(qinq)InThreading(p-rchild);/右子树线索化/if/InThreading第78页/共126页第七十九页,共126页。Status InOrderThreading(BiThrTree&Thrt,BiThrTree T)/构建中序线索链表 if(!(Thrt=(BiThrTree)malloc(sizeof(BiThrNode)exit(OVERFLOW);Thrt-LTag=Link;Thrt-RTag=Thread;Thrt-rchild=Thrt;/添加(tin ji)头结点 return OK;/InOrderThreading 第79页/共126页
38、第八十页,共126页。if(!T)Thrt-lchild=Thrt;else Thrt-lchild=T;pre=Thrt;InThreading(T);pre-rchild=Thrt;/处理最后(zuhu)一个结点 pre-RTag=Thread;Thrt-rchild=pre;第80页/共126页第八十一页,共126页。6.6 树和森林(snln)的 表示方法第81页/共126页第八十二页,共126页。树的三种存储(cn ch)结构一、双亲(shungqn)表示法二、孩子(hi zi)链表表示法三、树的二叉链表(孩子-兄弟)存储表示法第82页/共126页第八十三页,共126页。AB C D
39、EFG0 A-11 B 02 C 03 D 04 E 2 5 F 26 G 5r=0n=6data parent一、双亲(shungqn)表示法:第83页/共126页第八十四页,共126页。typedef struct PTNode Elem data;int parent;/双亲(shungqn)位置域 PTNode;data parent#define MAX_TREE_SIZE 100结点(ji din)结构:C语言的类型(lixng)描述:第84页/共126页第八十五页,共126页。typedef struct PTNode nodes MAX_TREE_SIZE;int r,n;/根
40、结点(ji din)的位置和结点(ji din)个数 PTree;树结构:第85页/共126页第八十六页,共126页。ABCDE FG0 A-11 B 02 C 03 D 04 E 25 F 26 G 5r=0n=6 data firstchild 1 2 34 56二、孩子(hi zi)链表表示法:-1000224第86页/共126页第八十七页,共126页。typedef struct CTNode int child;struct CTNode*next;*ChildPtr;孩子结点(ji din)结构:child nextC语言的类型(lixng)描述:第87页/共126页第八十八页,共
41、126页。typedef struct Elem data;ChildPtr firstchild;/孩子(hi zi)链的头指针 CTBox;双亲结点(ji din)结构 data firstchild第88页/共126页第八十九页,共126页。typedef struct CTBox nodesMAX_TREE_SIZE;int n,r;/结点(ji din)数和根结点(ji din)的位置 CTree;树结构:第89页/共126页第九十页,共126页。ABC DE FG AB C E D F Groot AB C E D F G 三、树的二叉链表(孩子-兄弟(xingd))存储表示法第9
42、0页/共126页第九十一页,共126页。typedef struct CSNode Elem data;struct CSNode*firstchild,*nextsibling;CSNode,*CSTree;C语言的类型(lixng)描述:结点(ji din)结构:firstchild data nextsibling第91页/共126页第九十二页,共126页。森林和二叉树的对应(duyng)关系设森林(snln)F=(T1,T2,Tn);T1=(root,t11,t12,t1m);二叉树 B=(LBT,Node(root),RBT);第92页/共126页第九十三页,共126页。由森林(sn
43、ln)转换成二叉树的转换规则为:若 F=,则 B=;否则,由 ROOT(T1)对应(duyng)得到 Node(root);由(t11,t12,t1m)对应(duyng)得到 LBT;由(T2,T3,Tn)对应(duyng)得到 RBT。第93页/共126页第九十四页,共126页。由二叉树转换(zhunhun)为森林的转换(zhunhun)规则为:若 B=,则 F=;否则,由 Node(root)对应(duyng)得到 ROOT(T1);由LBT 对应(duyng)得到(t11,t12,,t1m);由RBT 对应(duyng)得到(T2,T3,Tn)。第94页/共126页第九十五页,共126页
44、。96森林转换为二叉树的直观(zhgun)方法1.将森林的所有树的根和各棵树的兄弟分别(fnbi)相连;2.删除树中除根与左子树的所有分支线;3.把所有的水平线顺时针摆45度。第95页/共126页第九十六页,共126页。97第96页/共126页第九十七页,共126页。98第97页/共126页第九十八页,共126页。99二叉树转换为森林(snln)的直观方法1.把二叉树的所有的右子树分支线逆时针摆45度;2.将所有根和右孩子分别(fnbi)相连;3.删除树中所有水平线。第98页/共126页第九十九页,共126页。由此,树的各种操作(cozu)均可对应二叉树的操作(cozu)来完成。应当注意(zh
45、 y)的是,和树对应的二叉树,其左、右子树的概念已改变为:左是孩子,右是兄弟第99页/共126页第一百页,共126页。6.7树和森林(snln)的遍历第100页/共126页第一百零一页,共126页。一、树的遍历(bin l)二、森林(snln)的遍历三、树的遍历(bin l)的应用第101页/共126页第一百零二页,共126页。树的遍历可有三条(sn tio)搜索路径:按层次(cngc)遍历:先根(次序(cx)遍历:后根(次序)遍历:若树不空,则先访问根结点,然后依次先根遍历各棵子树。若树不空,则先依次后根遍历各棵子树,然后访问根结点。若树不空,则自上而下自左至右访问树中每个结点。第102页/
46、共126页第一百零三页,共126页。A B C DE F G H I J K 先根遍历时顶点的访问(fngwn)次序:A B E F C D G H I J K 后根遍历时顶点的访问(fngwn)次序:E F B C I J K H G D A 层次遍历时顶点(dngdin)的访问次序:A B C D E F G H I J K第103页/共126页第一百零四页,共126页。B C DE F G H I J K1。森林(snln)中第一棵树的根结点;2。森林(snln)中第一棵树的子树森林(snln);3。森林中其它(qt)树构成的森林。森林由三部分构成:第104页/共126页第一百零五页,共
47、126页。1.先序遍历(bin l)森林(snln)的遍历 若森林不空,则访问森林中第一棵树的根结点(ji din);先序遍历森林中第一棵树的子树森林;先序遍历森林中(除第一棵树之外)其 余树构成的森林。即:依次从左至右对森林中的每一棵树进行先根遍历。第105页/共126页第一百零六页,共126页。中序遍历(bin l)若森林不空,则中序遍历森林中第一棵树的子树森林;访问(fngwn)森林中第一棵树的根结点;中序遍历森林中(除第一棵树之外)其 余树构成的森林。即:依次从左至右对森林(snln)中的每一棵树进行后根遍历。第106页/共126页第一百零七页,共126页。树的遍历(bin l)和二叉
48、树遍历(bin l)的对应关系?先根遍历(bin l)后根遍历(bin l)树二叉树森林先序遍历 先序遍历中序遍历中序遍历第107页/共126页第一百零八页,共126页。设树的存储结构为孩子(hi zi)兄弟链表typedef struct CSNode Elem data;struct CSNode*firstchild,*nextsibling;CSNode,*CSTree;树的遍历算法的应用(yngyng):求树的深度第108页/共126页第一百零九页,共126页。int TreeDepth(CSTree T)if(!T)return 0;else h1=TreeDepth(T-firs
49、tchild);h2=TreeDepth(T-nextsibling);/TreeDepthreturn(max(h1+1,h2);求树的深度(shnd)的算法:第109页/共126页第一百一十页,共126页。6.8 哈 夫 曼 树 与 哈 夫 曼 编 码n 最优树的定义n 如何(rh)构造最优树n 前缀编码 第110页/共126页第一百一十一页,共126页。一、最优树的定义(dngy)树的路径(ljng)长度定义为:树中每个结点的路径(ljng)长度之和。结点的路径长度定义(dngy)为:从根结点到该结点的路径上 分支的数目。第111页/共126页第一百一十二页,共126页。树的带权路径长度
50、(chngd)定义为:树中所有叶子结点的带权路径长度(chngd)之和 WPL(T)=wklk(对所有叶子结点)在所有含 n 个叶子结点、并带相同权值的 m 叉树中,必存在(cnzi)一棵其带权路径长度取最小值的树,称为“最优树”。例如(lr):第112页/共126页第一百一十三页,共126页。27 9 75492WPL(T)=72+5 2+2 3+4 3+9 2=60WPL(T)=74+9 4+5 3+42+2 1=89 54第113页/共126页第一百一十四页,共126页。根据(gnj)给定的 n 个权值 w1,w2,wn,构造 n 棵二叉树的集合 F=T1,T2,Tn,其中每棵二叉树中均