计算机数据结构大学课件第六章.ppt_第1页
计算机数据结构大学课件第六章.ppt_第2页
计算机数据结构大学课件第六章.ppt_第3页
计算机数据结构大学课件第六章.ppt_第4页
计算机数据结构大学课件第六章.ppt_第5页
已阅读5页,还剩95页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第六章树和二叉树,2019年11月24日星期日,第2页,【学习目标】,1领会树和二叉树的类型定义2熟记二叉树的主要特性3熟练掌握二叉树的各种遍历算法4理解二叉树的线索化5熟练掌握二叉树和树的各种存储结构6掌握建立赫夫曼的方法。,2019年11月24日星期日,第3页,6.1树的定义和基本术语,树是由n(n0)个结点组成的有限集合。若n=0,称为空树;若n0,则:(1)其中必有一个称为根(root)的特定结点,它没有直接前驱,但有零个或多个直接后继;(2)除根结点以外的其它n-1结点可以划分为m(m0)个互不相交的有限集合T0,T1,Tm-1,每个集合Ti(i=0,1,m-1)又是一棵树,称为根的子树,每棵子树的根结点有且仅有一个直接前驱,但可以有0个或多个直接后继。由此可知,树的定义是一个递归的定义,即树的定义中又用到了树的概念。,2019年11月24日星期日,第4页,ADTTree数据对象D:,D是具有相同特性的数据元素的集合。,若D为空集,则称为空树。否则:(1)在D中存在唯一的称为根的数据元素root;(2)当n1时,其余结点可分为m(m0)个互不相交的有限集T1,T2,Tm,其中每一棵子集本身又是一棵符合本定义的树,称为根root的子树。,数据关系R:,2019年11月24日星期日,第5页,Root(T)/求树的根结点,基本操作,Value(T,cur_e)/求当前结点的元素值,Parent(T,cur_e)/求当前结点的双亲结点,LeftChild(T,cur_e)/求当前结点的最左孩子,RightSibling(T,cur_e)/求当前结点的右兄弟,TreeEmpty(T)/判定树是否为空树,TreeDepth(T)/求树的深度,TraverseTree(T,Visit()/遍历,2019年11月24日星期日,第6页,InitTree(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,Visit();,基本操作,2019年11月24日星期日,第17页,InitBiTree(,2019年11月24日星期日,第18页,ClearBiTree(,2019年11月24日星期日,第19页,6.2.2二叉树的性质,性质1:在二叉树的第i层上至多有2i-1个结点。(i1),2019年11月24日星期日,第21页,性质2:深度为k的二叉树上至多含2k-1个结点(k1)。,2019年11月24日星期日,第22页,性质3:对任何一棵二叉树,若它含有n0个叶子结点、n2个度为2的结点,则必存在关系式:n0=n2+1。,证明:,设二叉树上结点总数n=n0+n1+n2又二叉树上分支总数(即边数)b=n1+2n2而n=b+1=b=n-1=n0+n1+n2-1由此,n0=n2+1。,2019年11月24日星期日,第23页,两类特殊的二叉树:,满二叉树:指的是深度为k且含有2k-1个结点的二叉树。,完全二叉树:树中所含的n个结点和满二叉树中编号为1至n的结点一一对应。,2019年11月24日星期日,第24页,性质4:具有n个结点的完全二叉树的深度为log2n+1。,证明:,设完全二叉树的深度为k则根据第二条性质得2k-1-1n2k1或2k-1n2k即k-1log2nn,则该结点无右孩子结点,否则,编号为2i+1的结点为其右孩子结点。,2019年11月24日星期日,第26页,6.2.3二叉树的存储结构,2019年11月24日星期日,第27页,#defineMAX_TREE_SIZE100typedefTElemTypeSqBiTreeMAX_TREE_SIZE;SqBiTreebt;,一、二叉树的顺序存储表示,2019年11月24日星期日,第28页,例如:,A,B,C,D,E,F,ABDCEF,012345678910111213,1,4,0,13,2,6,将一棵二叉树按完全二叉树顺序存放到一个一维数组中,若该二叉树为非完全二叉树,则必须将相应位置空出来,使存放的结果符合完全二叉树形状。,2019年11月24日星期日,第29页,二、二叉树的链式存储表示,对于一棵二叉树,若采用顺序存贮时,当它为完全二叉树时,比较方便,若为非完全二叉树,将会浪费大量存贮存贮单元。最坏的非完全二叉树是全部只有右分支,设高度为K,则需占用2K-1个存贮单元,而实际只需k个存储单元。因此,对于非完全二叉树,宜采用链式存储结构。,2019年11月24日星期日,第30页,A,D,E,B,C,F,root,lchilddatarchild,结点结构:,1.二叉链表,2019年11月24日星期日,第31页,typedefstructBiTNodeTElemTypedata;structBiTNode*lchild,*rchild;BiTNode,*BiTree;,C语言的类型描述如下:,2019年11月24日星期日,第32页,StatusCreateBiTree(BiTree/CreateBiTree,2019年11月24日星期日,第33页,A,D,E,B,C,F,root,2三叉链表,parentlchilddatarchild,结点结构:,2019年11月24日星期日,第34页,typedefstructTriTNodeTElemTypedata;structTriTNode*lchild,*rchild;structTriTNode*parent;TriTNode,*TriTree;,parentlchilddatarchild,结点结构:,C语言的类型描述如下:,2019年11月24日星期日,第35页,dataparent,结点结构:,3双亲链表,LRTag,2019年11月24日星期日,第36页,typedefstructBPTNodeTElemTypedata;int*parent;charLRTag;BPTNodetypedefstructBPTreeBPTNodenodesMAX_TREE_SIZE;intnum_node;introot;BPTree,2019年11月24日星期日,第37页,6.3遍历二叉树和线索二叉树,2019年11月24日星期日,第38页,顺着某一条搜索路径巡访二叉树中的结点,使得每个结点均被访问一次,而且仅被访问一次。,2019年11月24日星期日,第39页,“遍历”是任何类型均有的操作,对线性结构而言,只有一条搜索路径(因为每个结点均只有一个后继),故不需要另加讨论。而二叉树是非线性结构,,每个结点有两个后继,则存在如何遍历即按什么样的搜索路径遍历的问题。,2019年11月24日星期日,第40页,遍历,先序的遍历算法,中序的遍历算法,后序的遍历算法,2019年11月24日星期日,第41页,若二叉树为空树,则空操作;否则,(1)访问根结点;(2)先序遍历左子树;(3)先序遍历右子树。,先序的遍历算法:,2019年11月24日星期日,第42页,若二叉树为空树,则空操作;否则,(1)中序遍历左子树;(2)访问根结点;(3)中序遍历右子树。,中序的遍历算法:,2019年11月24日星期日,第43页,若二叉树为空树,则空操作;否则,(1)后序遍历左子树;(2)后序遍历右子树;(3)访问根结点。,后序的遍历算法:,2019年11月24日星期日,第44页,最早提出遍历问题是对存储在计算机中的表达式求值。例如:(a+b*c)-d/e。该表达式用二叉树表示如下图所示。当对此二叉树进行先序、中序、后序遍历时,便可获得表达式的前缀、中缀、后缀书写形式:前缀:-+a*bc/de中缀:a+b*c-d/e后缀:abc*+de/-其中中缀形式是算术表达式的通常形式,只是没有括号。前缀表达式称为波兰表达式。算术表达式的后缀表达式被称作逆波兰表达式。在计算机内,使用后缀表达式易于求值。,图算术式的二叉树表示,2019年11月24日星期日,第45页,voidPreordertraverse(BiTreeT,void(*visit)(TElemTypePreordertraverse(T-rchild,visit,遍历算法的递归描述,2019年11月24日星期日,第46页,遍历算法的非递归描述,利用一个一维数组作为栈,来存储二叉链表中结点。,先序遍历二叉树的非递归算法,2019年11月24日星期日,第47页,算法如下:voidpreorder1(bitree*root)bitree*p,*s100;inttop=0;p=root;while(p!=NULL)|(top0)while(p!=NULL)printf(“%c”,p-data);s+top=p;p=p-lchild;p=stop-;p=p-rchild;,【算法】先序遍历二叉树的非递归算法,2019年11月24日星期日,6.3.2线索二叉树,2019年11月24日星期日,第49页,对线索链表中结点的约定:,在二叉链表的结点中增加两个标志域,并作如下规定:,若该结点的左子树不空,则Lchild域的指针指向其左子树,且左标志域的值为“指针Link”;否则,Lchild域的指针指向其“前驱”,且左标志的值为“线索Thread”。,2019年11月24日星期日,第50页,若该结点的右子树不空,则rchild域的指针指向其右子树,且右标志域的值为“指针Link”;否则,rchild域的指针指向其“后继”,且右标志的值为“线索Thread”。,如此定义的二叉树的存储结构称作“线索链表”。,2019年11月24日星期日,第51页,typedefstructBiThrNodTElemTypedata;structBiThrNode*lchild,*rchild;PointerThrLTag,RTag;BiThrNode,*BiThrTree;,线索链表的类型描述:,typedefenumLink,ThreadPointerThr;/Link=0,Thread=1:,2019年11月24日星期日,第52页,1)在中序线索树中找前驱结点根据线索二叉树的基本概念和存储结构可知,对于结点p,当p-Ltag=1时,p-LChild指向p的前驱。当p-Ltag=0时,p-LChild指向p的左孩子。由中序遍历的规律可知,作为根p的前驱结点,它是中序遍历p的左子树时访问的最后一个结点,2019年11月24日星期日,第53页,2)在中序线索树中找结点后继对于结点p,若要找其后继结点,当p-Rtag=1时,p-RChild即为p的后继结点;当p-Rtag=0时,说明p有右子树,此时p的中序后继结点即为其右子树的最左下端的结点。,2019年11月24日星期日,第54页,线索链表的遍历算法:,在线索二叉树中,由于有线索存在,在某些情况下可以方便地找到指定结点在某种遍历序列中的直接前驱或直接后继。此外,在线索二叉树上进行某种遍历比在一般的二叉树上进行这种遍历要容易得多,不需要设置堆栈,且算法十分简洁。,2019年11月24日星期日,第55页,voidInOrderTraverse_Thr(BiThrTreeT,void(*Visit)(TElemTypee)p=T-lchild;while(p!=T)while(p-LTag=Link)p=p-lchild;if(!Visit(p-data)returnERROR;while(p-RTag=Thread/InOrderTraverse_Thr,2019年11月24日星期日,第56页,在中序遍历过程中修改结点的左、右指针域,以保存当前访问结点的“前驱”和“后继”信息。遍历过程中,附设指针pre,并始终保持指针pre指向当前访问的、指针p所指结点的前驱。,如何建立线索链表?,2019年11月24日星期日,第57页,voidInThreading(BiThrTreep)if(p)InThreading(p-lchild);if(!p-lchild)p-LTag=Thread;p-lchild=pre;if(!pre-rchild)pre-RTag=Thread;pre-rchild=p;pre=p;InThreading(p-rchild);/if/InThreading,2019年11月24日星期日,第58页,StatusInOrderThreading(BiThrTree/InOrderThreading,2019年11月24日星期日,第59页,if(!T)Thrt-lchild=Thrt;elseThrt-lchild=T;pre=Thrt;InThreading(T);pre-rchild=Thrt;pre-RTag=Thread;Thrt-rchild=pre;,2019年11月24日星期日,第60页,6.4树和森林,2019年11月24日星期日,第61页,6.4.1树的存储结构,一、双亲表示法,二、孩子链表表示法,三、树的二叉链表表示法,2019年11月24日星期日,第62页,A,B,C,D,E,F,G,0A-11B02C03D04E25F26G5,r=0n=6,dataparent,一、双亲表示法:,2019年11月24日星期日,第63页,typedefstructPTNodeElemdata;intparent;PTNode;,dataparent,#defineMAX_TREE_SIZE100,C语言的类型描述:,2019年11月24日星期日,第64页,typedefstructPTNodenodesMAX_TREE_SIZE;intr,n;/根结点的位置和结点个数PTree;,2019年11月24日星期日,第65页,A,B,C,D,E,F,G,0A-11B02C03D04E25F26G5,r=0n=6,datafirstchild,123,45,6,二、孩子链表表示法:,-1000224,2019年11月24日星期日,第66页,typedefstructCTNodeintchild;structCTNode*next;*ChildPtr;,childnext,C语言的类型描述:,2019年11月24日星期日,第67页,typedefstructElemdata;ChildPtrfirstchild;CTBox;,结点,datafirstchild,2019年11月24日星期日,第68页,typedefstructCTBoxnodesMAX_TREE_SIZE;intn,r;CTree;,2019年11月24日星期日,第69页,A,B,C,D,E,F,G,ABCEDFG,root,三、树的二叉链表存储表示法,2019年11月24日星期日,第70页,typedefstructCSNodeElemdata;structCSNode*firstchild,*nextsibling;CSNode,*CSTree;,C语言的类型描述:,firstchilddatanextsibling,6.4.2森林与二叉树的转换,2019年11月24日星期日,第72页,图树与二叉树的对应,2019年11月24日星期日,第73页,1.森林转换为二叉树森林是若干棵树的集合。树可以转换为二叉树,森林同样也可以转换为二叉树。因此,森林也可以方便地用孩子兄弟链表表示。,2019年11月24日星期日,第74页,图森林转换为二叉树的过程,2019年11月24日星期日,第75页,将森林F看作树的有序集F=T1,T2,,TN,它对应的二叉树为B(F):(1)若N=0,则B(F)为空。(2)若N0,二叉树B(F)的根为森林中第一棵树T1的根;B(F)的左子树为B(T11,T1m),其中T11,T1m是T1的子树森林;B(F)的右子树是B(T2,TN)。,2019年11月24日星期日,第76页,2.二叉树转换为森林森林可以转换为二叉树,森林转换后的二叉树,其根结点有右孩子。,2019年11月24日星期日,第77页,同样,我们可以用递归的方法描述上述转换过程。若B是一棵二叉树,T是B的根结点,L是B的左子树,R为B的右子树,且B对应的森林F(B)中含有的n棵树为T1,T2,Tn,则有:(1)B为空,则F(B)为空的森林(n0)。(2)B非空,则F(B)中第一棵树T1的根为二叉树B的根T;T1中根结点的子树森林由B的左子树L转换而成,即F(L)=T11,T1m;B的右子树R转换为F(B)中其余树组成的森林,即F(R)T2,T3,Tn。,2019年11月24日星期日,第78页,6.4.3树和森林的遍历,2019年11月24日星期日,第79页,一、树的遍历,二、森林的遍历,2019年11月24日星期日,第80页,树的遍历可有三条搜索路径:,按层次遍历:,先根(次序)遍历:,后根(次序)遍历:,若树不空,则先访问根结点,然后依次先根遍历各棵子树。,若树不空,则先依次后根遍历各棵子树,然后访问根结点。,若树不空,则自上而下自左至右访问树中每个结点。,2019年11月24日星期日,第81页,1.先序遍历,森林的遍历,若森林不空,则访问森林中第一棵树的根结点;先序遍历森林中第一棵树的子树森林;先序遍历森林中(除第一棵树之外)其余树构成的森林。,2019年11月24日星期日,第82页,中序遍历,若森林不空,则中序遍历森林中第一棵树的子树森林;访问森林中第一棵树的根结点;中序遍历森林中(除第一棵树之外)其余树构成的森林。,即:依次从左至右对森林中的每一棵树进行后根遍历。,2019年11月24日星期日,第83页,6.6哈夫曼树及其应用,2019年11月24日星期日,第84页,6.6.1赫夫曼树,赫夫曼(Huffman)树又称最优树,是一类带权路径长度最短的树,有着广泛的应用。,结点路径:从树中一个结点到另一个结点的之间的分支构成这两个结点之间的路径。路径长度:结点路径上的分支数目称为路径长度。树的路径长度:从树根到每一个结点的路径长度之和。,基本概念,结点的带权路径长度:从该结点的到树的根结点之间的路径长度与结点的权(值)的乘积。权(值):各种开销、代价、频度等的抽象称呼。树的带权路径长度:树中所有叶子结点的带权路径长度之和,记做:WPL=w1l1+w2l2+wnln=wi*li(i=1,2,n)其中:n为叶子结点的个数;wi为第i个结点的权值;li为第i个结点的路径长度。,基本概念,Huffman树:具有n个叶子结点(每个结点的权值为wi)的二叉树不止一棵,但在所有的这些二叉树中,必定存在一棵WPL值最小的树,称这棵树为Huffman树(或称最优树)。在许多判定问题时,利用Huffman树可以得到最佳判断算法。,基本概念,2019年11月24日星期日,第88页,WPL=72+52+23+43+92=60,2019年11月24日星期日,第89页,根据给定的n个权值w1,w2,wn,构造n棵二叉树的集合F=T1,T2,Tn,其中每棵二叉树中均只含一个带权值为wi的根结点,其左、右子树为空树;,二、如何构造最优树,(1),(赫夫曼算法)以二叉树为例:,2019年11月24日星期日,第90页,在F中选取其根结点的权值为最小的两棵二叉树,分别作为左、右子树构造一棵新的二叉树,并置这棵新的二叉树根结点的权值为其左、右子树根结点的权值之和;,(2)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论