数据结构-第六章-树与二叉树课件.ppt

上传人(卖家):晟晟文业 文档编号:4106207 上传时间:2022-11-11 格式:PPT 页数:98 大小:370.80KB
下载 相关 举报
数据结构-第六章-树与二叉树课件.ppt_第1页
第1页 / 共98页
数据结构-第六章-树与二叉树课件.ppt_第2页
第2页 / 共98页
数据结构-第六章-树与二叉树课件.ppt_第3页
第3页 / 共98页
数据结构-第六章-树与二叉树课件.ppt_第4页
第4页 / 共98页
数据结构-第六章-树与二叉树课件.ppt_第5页
第5页 / 共98页
点击查看更多>>
资源描述

1、第六章 树和二叉树树的概念和基本术语树的概念和基本术语 二叉树二叉树 二叉树遍历二叉树遍历二叉树的计数二叉树的计数 树与森林树与森林霍夫曼树霍夫曼树 树的概念和基本术语树的概念和基本术语树的定义树的定义树是由树是由 n(n 0)个结点的有限集合。如个结点的有限集合。如果果 n=0,称为空树;如果,称为空树;如果 n 0,则,则 有且仅有一个特定的称之为根有且仅有一个特定的称之为根(Root)的结的结点,它只有直接后继,但没有直接前驱;点,它只有直接后继,但没有直接前驱;当当n 1,除根以外的其它结点划分为,除根以外的其它结点划分为 m(m 0)个互不相交的有限集个互不相交的有限集 T1,T2,

2、Tm,其中每个集合本身又是一棵树,并且称为其中每个集合本身又是一棵树,并且称为根的子树根的子树(SubTree)ACGBDEFKLHMIJ例如例如A只有根结点的树只有根结点的树有有13个结点的树个结点的树其中:其中:A是根;其余结点分成三个互不相交的子集,是根;其余结点分成三个互不相交的子集,T1=B,E,F,K,L;T2=C,G;T3=D,H,I,J,M,T1,T2,T3都是根都是根A的子树,且本身也是一棵树的子树,且本身也是一棵树树的基本术语1层2层4层3层height=4ACGBDEFKLHMIJ结点:一个数据元素及指向其子树的分支。结点:一个数据元素及指向其子树的分支。结点的度:结点拥

3、有的子树个数。结点的度:结点拥有的子树个数。叶结点:度为零的结点。叶结点:度为零的结点。子女:结点子树的根。子女:结点子树的根。兄弟:同一结点子女。兄弟:同一结点子女。祖先:根到该结点路径上的所有结点。祖先:根到该结点路径上的所有结点。子孙:某结点为根的子树上的任意结点。子孙:某结点为根的子树上的任意结点。结点层次:从根开始,根为第一层,根的子女为结点层次:从根开始,根为第一层,根的子女为第二层,以此类推。第二层,以此类推。树的深度(高度):树中结点的最大层次数。树的深度(高度):树中结点的最大层次数。有序树:树中结点的子树由左向右有序。有序树:树中结点的子树由左向右有序。森林:森林:m(m

4、0)棵互不相交的树。棵互不相交的树。二叉树二叉树(Binary Tree)定义定义五种形态五种形态一棵二叉树是结点的一个有限集合,一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根结点加该集合或者为空,或者是由一个根结点加上两棵分别称为左子树和右子树的、互不上两棵分别称为左子树和右子树的、互不相交的二叉树组成。相交的二叉树组成。LLRR特点特点每个结点至多只有两棵子树(二叉树中每个结点至多只有两棵子树(二叉树中不存在度大于不存在度大于2的结点)的结点)性质性质1 在二叉树的第在二叉树的第 i 层上至多有层上至多有 2i 1个结点。个结点。(i 1)证明用归纳法证明用归纳法证明:当证

5、明:当i=1时,只有根结点,时,只有根结点,2 i-1=2 0=1。假设对所有假设对所有j,ij 1,命题成立,即第,命题成立,即第j层层上至多有上至多有2 j-1 个结点。个结点。由归纳假设第由归纳假设第i-1 层上至多有层上至多有 2i 2个结点。个结点。由于二叉树的每个结点的度至多为由于二叉树的每个结点的度至多为2,故在,故在第第i层上的最大结点数为第层上的最大结点数为第i-1层上的最大结层上的最大结点数的点数的2倍,即倍,即2*2i 2=2 i-1。性质性质性质性质2 深度为深度为 k 的二叉树至多有的二叉树至多有 2k-1个结点个结点(k 1)。证明:由性质证明:由性质1可见,深度为

6、可见,深度为k的二叉树的的二叉树的最大结点数为最大结点数为 kii11220+21+2k-1=2k-1kii1(层上的最大结点数)第性质性质3 对任何一棵二叉树对任何一棵二叉树T,如果其叶如果其叶结点数为结点数为 n0,度为度为2的结点数为的结点数为 n2,则则n0n21.证明:若度为证明:若度为1的结点有的结点有 n1 个,总结点个个,总结点个数为数为 n,总边数为,总边数为 e,则根据二叉树的定,则根据二叉树的定义,义,n=n0+n1+n2 e=2n2+n1=n-1因此,有因此,有 2n2+n1=n0+n1+n2-1 n2=n0-1 n0=n2+1 定义定义1 满二叉树满二叉树(Full

7、Binary Tree)一棵深度为一棵深度为k且有且有2k-1个结点的二叉树称为满个结点的二叉树称为满二叉树。二叉树。两种特殊形态的二叉树两种特殊形态的二叉树621754389 10 1113 14 1512满二叉树满二叉树215436 7216543非完全二叉树非完全二叉树定义定义2 完全二叉树完全二叉树(Complete Binary Tree)若设二叉树的高度为若设二叉树的高度为h,则共有,则共有h层。除层。除第第 h 层外,其它各层层外,其它各层(0 h-1)的结点数都的结点数都达到最大个数,第达到最大个数,第 h 层层从右向左从右向左连续缺若干连续缺若干结点,这就是完全二叉树。结点,

8、这就是完全二叉树。621754389 10 11 12完全二叉树完全二叉树性质性质4 具有具有 n 个结点的完全二叉树的深度个结点的完全二叉树的深度为为 log2(n)1证明:证明:设完全二叉树的深度为设完全二叉树的深度为 h,则根据性,则根据性质质2和完全二叉树的定义有和完全二叉树的定义有2h1-1 n 2h-1或或 2h1 n 2h取对数取对数 h1 log2n 0,则则 i 的双亲为的双亲为(i-1)/2 n 若若2*i+1 n,则则 i 的左子女为的左子女为 2*i+1,若,若2*i+2-leftChild);Visit(T-data);InOrder(T-rightChild);中序

9、遍历二叉树的递归算法中序遍历二叉树的递归算法前序遍历二叉树算法的定义:若二叉树为空,则空操作;否则访问根结点(V);前序遍历左子树(L);前序遍历右子树(R)。遍历结果-+a*b-c d/e f前序遍历(Preorder Traversal)前序遍历二叉树的递归算法前序遍历二叉树的递归算法void PreOrder(BinTreeNode*T)if(T!=NULL)Visit(T-data);PreOrder(T-leftChild);PreOrder(T-rightChild);后序遍历二叉树算法的定义:若二叉树为空,则空操作;否则后序遍历左子树(L);后序遍历右子树(R);访问根结点(V)

10、。遍历结果 a b c d-*+e f/-后序遍历(Postorder Traversal)后序遍历二叉树的递归算法:后序遍历二叉树的递归算法:void PostOrder(BinTreeNode*T)if(T!=NULL)PostOrder(T-leftChild);PostOrder(T-rightChild);Visit(T-data);二叉树遍历应用以递归方式建立二叉树。输入结点值的顺序必须对应二叉树结点前序遍历的顺序。并约定以输入序列中不可能出现的值作为空结点的值以结束递归,此值在RefValue中。例如用“”或用“-1”表示字符序列或正整数序列空结点。1.按前序建立二叉树按前序建立

11、二叉树(递归算法递归算法)如图所示的二叉树的前序遍历顺序为如图所示的二叉树的前序遍历顺序为A B C D E G F ABCDEGF Status CreateBiTree(BiTree&T)scanf(&ch);/读入根结点的值读入根结点的值 if(ch=)T=NULL;else if(!(T=(BiTNode*)malloc(sizeof(BiTNode)exit(OVERFLOW);/建立根结点建立根结点 T-data=ch;CreateBiTree(T-leftChild);CreateBiTree(T-rightChild);return OK;/CreateBiTree2.计算二叉

12、树结点个数(递归算法)int Count(BinTreeNode*T)if(T=NULL)return 0;else return 1+Count(T-leftChild)+Count(T-rightChild);2.计算二叉树结点个数(递归算法)3.求二叉树中叶子结点的个求二叉树中叶子结点的个数数int Leaf_Count(Bitree T)/求二叉树中叶子结点的数目求二叉树中叶子结点的数目if(!T)return 0;/空树没有叶子空树没有叶子 elseif(!T-lchild&!T-rchild)return 1;/叶子结点叶子结点 else return Leaf_Count(T-l

13、child)+Leaf_Count(T-rchild);/左子树的叶子数加上右子树的叶子数左子树的叶子数加上右子树的叶子数3.求二叉树中叶子结点的个求二叉树中叶子结点的个数数4.求二叉树高度求二叉树高度(递归算法递归算法)int Height(BinTreeNode*T)if(T=NULL)return 0 0;elseint m=Height(T-leftChild);int n=Height(T-rightChild);return(m n)?m+1:n+1;4.求二叉树高度求二叉树高度(递归算法递归算法)5.复制二叉树复制二叉树(递归算法递归算法)5.复制二叉树复制二叉树(递归算法递归算

14、法)BiTNode*Copy(BinTreeNode*T)if(T=NULL)return NULL;if(!(Temp=(BiTNode*)malloc(sizeof(BiTNode)exit(OVERFLOW);Temp-data=T-data;Temp-leftChild=Copy(T-leftChild);Temp-rightChild=Copy(T-rightChild);return Temp;6.判断二叉树等价判断二叉树等价(递归算法递归算法)6.判断二叉树等价判断二叉树等价(递归算法递归算法)int Equal(BinTreeNode*a,BinTreeNode*b)if(a=

15、NULL&b=NULL)return 1;if(a!=NULL&b!=NULL&a-data=b-data&equal(a-leftChild,b-leftChild)&equal(a-rightChild,b-rightChild)return 1;return 0;/如果如果a和和b的子树不等同,则函数返回的子树不等同,则函数返回0中序遍历二叉树中序遍历二叉树(非递归算法非递归算法)用栈实现用栈实现baabcdeadaaa b入栈入栈b退栈退栈访问访问d入栈入栈d退栈退栈访问访问e 退栈退栈 访问访问ecc栈空栈空 a退栈退栈访问访问c e 入栈入栈c 退栈退栈 访问访问 void InO

16、rder(BinTree T)stack S;InitStack(&S);/递归工作栈递归工作栈 Push(S,T);/初始化初始化 while(!StackEmpty(S)while(GetTop(S,p)&p)Push(S,p-lchild);Pop(S,p);if(!StackEmpty(S)/栈非空栈非空 Pop(S,p);/退栈退栈 Visit(p-data);/访问根访问根 Push(S,p-rchild);/if /while return ok;abcde前序遍历二叉树前序遍历二叉树(非递归算法非递归算法)用栈实现用栈实现acabcdedcc访问访问a进栈进栈c左进左进b访问访

17、问b进栈进栈d左进左进空空退栈退栈d访问访问d左进左进空空退栈退栈c访问访问c左进左进e访问访问e左进左进空空退栈退栈 结束结束void PreOrder(BinTree T)stack S;InitStack(S);/递归工作栈递归工作栈 BinTreeNode*p=T;Push(S,NULL);while(p!=NULL)Visit(p-data);if(p-rightChild!=NULL)Push(S,p-rightChild);if (p-leftChild!=NULL)p=p-leftChild;/进左子树进左子树 else Pop(S,p);abcdev后序遍历二叉树后序遍历二叉

18、树(非递归算法非递归算法)用栈实现用栈实现后序遍历时使用的栈的结点定义后序遍历时使用的栈的结点定义typedef struct BinTreeNode*ptr;/结点指针结点指针 enum tag L,R;/该结点退栈标记该结点退栈标记 StackNode;根结点的根结点的 tag=L,表示从左子树退出,表示从左子树退出,访问右子树。访问右子树。tag=R,表示表示从右子树退出从右子树退出,访问根。访问根。ptr tagL,R vvoid PostOrder(BinTree T)stack S;InitStack(S);StackNode w;BinTreeNode*p=T;do while(

19、p!=NULL)/向左子树走向左子树走 w.ptr=p;w.tag=L;Push(S,w);p=p-leftChild;int continue=1;/继续循环标记继续循环标记 while(continue&!StackEmpty(S)Pop(S,w);p=w.ptr;switch(w.tag)/判断栈顶判断栈顶tag标记标记 case L:w.tag=R;Push(S,w);continue=0;p=p-rightChild;break;case R:Visit(p-data);while(p!=NULL|!StackEmpty(S);练习:交换二叉树各结点的左、右子树(递归算法)练习:交换

20、二叉树各结点的左、右子树(递归算法)void unknown(BinTreeNode*T)BinTreeNode*p=T,*temp;if(p!=NULL)temp=p-leftChild;p-leftChild=p-rightChild;p-rightChild=temp;unknown(p-leftChild);unknown(p-rightChild);void unknown(BinTreeNode*T)BinTreeNode*p=T,*temp;while(p!=NULL)temp=p-leftChild;p-leftChild=p-rightChild;p-rightChild=t

21、emp;unknown(p-leftChild);p=p-rightChild;不用栈消去递归算法中的第二个递归语句不用栈消去递归算法中的第二个递归语句 使用栈消去递归算法中的两个递归语句void unknown(BinTreeNode*T)BinTreeNode*p,*temp;stack S;InitEmpty(&S);if(T!=NULL)push(&S,T);while(!StackEmpty(&S)Pop(&S,p);/栈中退出一个结点栈中退出一个结点 temp=p-leftChild;/交换子女交换子女 p-leftChild=p-rightChild;p-rightChild=t

22、emp;if(p-rightChild!=NULL)push(&S,p-rightChild);if(p-leftChild!=NULL)push(&S,p-leftChild);对二叉树遍历的过程实质上是对一个非线对二叉树遍历的过程实质上是对一个非线性结构进行线性化的操作性结构进行线性化的操作.以二叉链表为存储结构时以二叉链表为存储结构时,结点的左右孩子结点的左右孩子可以直接找到可以直接找到,但不能直接找到结点的前但不能直接找到结点的前驱和后继驱和后继,而结点的前驱和后继只有在遍而结点的前驱和后继只有在遍历二叉树的过程中才能得到历二叉树的过程中才能得到.用二叉链表表示的二叉树中用二叉链表表示

23、的二叉树中,n个结点的二个结点的二叉树有叉树有n+1个空链域,可利用这些空链域个空链域,可利用这些空链域存储结点的前驱或后继。存储结点的前驱或后继。v线索二叉树线索二叉树(Threaded Binary Tree)LeftThread=0,LeftChild为为左子女指针左子女指针LeftThread=1,LeftChild为为前驱线索前驱线索RightThread=0,RightChild为为右子女指针右子女指针RightThread=1,RightChild为为后继指针后继指针LeftThreadRightThread结点结构结点结构typedef enum Link,Thread Poi

24、nterTag;/PointerTag为标志,为标志,Link=0代表指针,代表指针,Thread=1代表线索代表线索typedef struct BiThrNodeTElemType data;struct BiThrNode*lchild,*rchild;PointerTag LTag,RTag;BiThrNode,*BiThrTree;中序线索二叉树中序线索二叉树BDAEC中序线索二叉树中序线索二叉树后继:结点标志为后继:结点标志为1时,其右指针为其后继;时,其右指针为其后继;结点标志为结点标志为0时,其右子树最左下结点为时,其右子树最左下结点为其后继。其后继。前驱:结点标志为前驱:结点

25、标志为1时,其左指针为其前驱;时,其左指针为其前驱;结点标志为结点标志为0时,其左子树最右下结点为时,其左子树最右下结点为其前驱。其前驱。abcde后序线索二叉树后序线索二叉树后继后继:(1)根的后继为空。根的后继为空。(2)如果结点是双亲的右孩子或是左如果结点是双亲的右孩子或是左孩子但双亲没有右子树,则后继是其双孩子但双亲没有右子树,则后继是其双亲。亲。(3)如果结点是双亲的左孩子且双亲如果结点是双亲的左孩子且双亲有右子树,则后继是双亲右子树上先遍有右子树,则后继是双亲右子树上先遍历到的结点。历到的结点。总之,如果二叉树的应用主要是遍历或查总之,如果二叉树的应用主要是遍历或查找结点的前驱和后

26、继则使用线索二叉树找结点的前驱和后继则使用线索二叉树更为合适。更为合适。Status InOrderTraverse_Thr(BiThrTree T,Status(*Visit)(TElemType e)p=T-lchild;while(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);p=p-rchild;/InOrderTraverse_Thrvoid InThreading(BiThrTree p)

27、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;/保持保持pre为下一结点的前驱为下一结点的前驱InThreading(p-rchild);/右子树线索化右子树线索化/InThreading通过中序遍历建立中序线索化二叉树Status InOrderThreading(BiThrTree&Thrt,BiThrTree T)/中序遍历并

28、线索化二叉树,中序遍历并线索化二叉树,Thrt为头结点为头结点if(!(Thrt=(BiThrTree)malloc(sizeof(BiThrNode)exit(OVERFLOW);/建头结点建头结点Thrt-LTag=Link;Thrt-RTag=Thread;Thrt-rchild=Thrt;/头结点右指针回指头结点右指针回指if(!T)Thrt-lchild=Thrt;/如果二叉树为空,则左指针也回指如果二叉树为空,则左指针也回指elseThrt-lchild=T;pre=Thrt;/pre总是指向最后一个访问过的结总是指向最后一个访问过的结点,也就是其后要访问结点的前驱点,也就是其后要

29、访问结点的前驱InThreading(T);/线索化的主过程线索化的主过程pre-rchild=Thrt;pre-RTag=Thread;Thrt-rchild=pre;/将最后一个结点线索化将最后一个结点线索化return OK;/InOrderThreadingq树的存储结构树的存储结构双亲表示:以一组连续空间存储树的结点,双亲表示:以一组连续空间存储树的结点,同时在同时在结点中附设一个指针,存放双亲结点结点中附设一个指针,存放双亲结点在链表中的位置。该方法利用每个结点只有在链表中的位置。该方法利用每个结点只有一个双亲的特点,可以很方便求结点的双亲,一个双亲的特点,可以很方便求结点的双亲,

30、但不方便求结点的孩子。但不方便求结点的孩子。树与森林ABCDEFGdataparentA B C D E F G-1 0 0 0 1 1 30 1 2 3 4 5 6用双亲表示实现的树定义用双亲表示实现的树定义#define MaxSize100 /最大结点个数最大结点个数typedef char TreeData;/结点数据结点数据typedef struct /树结点定义树结点定义 TreeData data;int parent;TreeNode;typedef TreeNode TreeMaxSize;/树树ABCDEFG孩子表示法孩子表示法(多重链表多重链表)第一种解决方案第一种解决

31、方案 等数量的链域等数量的链域(d为树的度为树的度)data child1child2child3childdABCDEFG 空链域n(d-1)+1个第二种解决方案第二种解决方案 孩子链表孩子链表将每个结点的孩子链在该结点之后组成将每个结点的孩子链在该结点之后组成链表,再将所有头结点组成一个线性表。链表,再将所有头结点组成一个线性表。typedef struct CTNode int child;struct CTNode*next;*ChildPtr;typedef structTElemType data;ChildPtr firstchild;CTBox;typedef structCT

32、Box nodesMAX_TREE_SIZE;int n,r;/结点数和根的位置结点数和根的位置CTree;ABCDEFG0 A1 B2 C 3 D4 E 5 F 6 G 123 45 6 结点结构结点结构 datafirstChildnextSiblingABCDEFG空链域n+1个树的左子女树的左子女-右兄弟表示右兄弟表示(二叉链表表示)(二叉链表表示)BCDGFE A typedef char TreeData;typedef struct node TreeData data;struct node*firstChild,*nextSibling;TreeNode;typedef Tr

33、eeNode*Tree;用左子女-右兄弟表示实现的树定义T1 T2 T3T1 T2 T3AFHB C DGIJEKAFBCDEGHIKJABCEDHIKJFG3 棵树的森林各棵树的二叉树表示森林的二叉树表示q森林与二叉树的转换森林与二叉树的转换树的二叉树表示树的二叉树表示:q树的遍历深度优先遍历 先根次序遍历 后根次序遍历ABCDE FGABCEDGF深度优先遍历当树非空时 访问根结点 依次先根遍历根的各棵 子树树先根遍历 ABEFCDG对应二叉树前序遍历 ABEFCDG树的先根遍历结果与其对应二叉树 表示的前序遍历结果相同树的先根遍历可以借助对应二叉树的前序遍历算法实现ABCEDGF树的树的

34、先根次序先根次序遍历遍历ABCDEFG树的后根次序遍历:当树非空时依次后根遍历根的各棵 子树访问根结点树后根遍历 EFBCGDA对应二叉树中序遍历 EFBCGDA树的后根遍历结果与其对应二叉树 表示的中序遍历结果相同树的后根遍历可以借助对应二叉树的中序遍历算法实现ABCEDGFABCDEFG二叉树的计数由二叉树的前序序列和中序序列可唯一地确定一棵二叉树。例,前序序列 ABHFDECKG 和中序序列 HBDFAEKCG,构造二叉树过程如下:HBDFEKCGAEKCGABHDFKCGEKCGABHDFEKCGABHFDEABHFDEABHFDCKG 如果前序序列固定不变,给出不同的中序如果前序序列

35、固定不变,给出不同的中序序列,可得到不同的二叉树。序列,可得到不同的二叉树。612345789612375849固定前序排列固定前序排列,选择所有可能的中序排列选择所有可能的中序排列,可以构造多少种不同的二叉树?可以构造多少种不同的二叉树?例如例如,有有 3 个数据个数据 1,2,3,可得,可得 5 种不种不同的二叉树。它们的前序排列均为同的二叉树。它们的前序排列均为 123,中,中序序列可能是序序列可能是 321,231,213,132,123.123123123123123具有具有n个结点不同形态的树的数目和具有个结点不同形态的树的数目和具有n-1个结点互不相似的二叉树的数目相同。个结点互

36、不相似的二叉树的数目相同。有有0个个,1个个,2个个,3个结点的不同二叉树如下个结点的不同二叉树如下b0=1b1=1b2=2b3=5 b4=14!)!(211112nnnnnbCnnnv计算具有计算具有 n 个结点的不同二叉树的棵数个结点的不同二叉树的棵数最终结果:最终结果:1101niininbbb霍夫曼树(Huffman Tree)路径长度路径长度(Path Length)两个结点之间的两个结点之间的路径长度路径长度 PL 是连接两结是连接两结点的路径上的分支数。点的路径上的分支数。树的外部路径长度是各叶结点树的外部路径长度是各叶结点(外结点外结点)到到根结点的路径长度之和根结点的路径长度

37、之和 EPL。树的内部路径长度是各非叶结点树的内部路径长度是各非叶结点(内结点内结点)到根结点的路径长度之和到根结点的路径长度之和 IPL。树的路径长度树的路径长度 PL=EPL+IPL123456782345678树的外部路径长度树的外部路径长度EPL=3*1+2*3=9树的外部路径长度树的外部路径长度EPL=1*1+2*1+3*1+4*1=101带权路径长度带权路径长度(Weighted Path Length,WPL)二叉树的带权二叉树的带权(外部外部)路径长度是树的各路径长度是树的各叶结点所带的权值叶结点所带的权值 wi 与该结点到根的路径长与该结点到根的路径长度度 li 的乘积的和。

38、的乘积的和。10niiilwWPLWPL=2*2+WPL=2*1+WPL=7*1+4*2+5*2+4*2+5*3+5*2+2*3+7*2=36 7*3=46 4*3=35 222444555777带权带权(外部外部)路径路径长度达到最小长度达到最小霍夫曼树带权路径长度达到最小的二叉树即为霍夫曼树。在霍夫曼树中,权值大的结点离根最近。(1)由给定的由给定的 n 个权值个权值 w0,w1,w2,wn-1,构造具有构造具有 n 棵扩充二叉树的森林棵扩充二叉树的森林 F=T0,T1,T2,Tn-1,其中每棵扩充二叉树,其中每棵扩充二叉树 Ti 只有一只有一 个带权值个带权值 wi 的根结点的根结点,其

39、左、右子树均为空。其左、右子树均为空。霍夫曼霍夫曼算法算法(2)重复以下步骤重复以下步骤,直到直到 F 中仅剩下一棵中仅剩下一棵树为止:树为止:在在 F 中选取两棵根结点的权值最小的中选取两棵根结点的权值最小的扩充二叉树扩充二叉树,做为左、右子树构造一棵新做为左、右子树构造一棵新的二叉树。置新的二叉树的根结点的权值的二叉树。置新的二叉树的根结点的权值为其左、右子树上根结点的权值之和。为其左、右子树上根结点的权值之和。在在 F 中删去这两棵二叉树。中删去这两棵二叉树。把新的二叉树加入把新的二叉树加入 F。F:7 5 2 4F:7 5 6F:7 11 7524初始合并2 475246F:18 11

40、75246合并5 65合并7 11 27461118举例霍夫曼树的构造过程举例霍夫曼树的构造过程5274Weight parent leftChild rightChild7 -1 -1 -15 -1 -1 -12 -1 -1 -14 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -10123456上例存储结构上例存储结构初初 态态52746Weight parent leftChild rightChild 7 -1 -1 -1 5 -1 -1 -1 2 -1 -1 -1 4 -1 -1 -1 6 -1 -1 -1 -1 -1 -1 -1 -1 -10123456p1p2

41、4423i过过 程程5274611Weight parent leftChild rightChild 7 -1 -1 -1 5 -1 -1 -1 2 4 -1 -1 4 4 -1 -1 6 -1 2 311 -1 -1 -1 -1 -1 -10123456p1p25514i5274611Weight parent leftChild rightChild 7 -1 -1 -1 5 5 -1 -1 2 4 -1 -1 4 4 -1 -1 6 5 2 311 -1 1 418 -1 -1 -10123456p1p26605i18终终 态态const int n=20;/叶结点数叶结点数const

42、 int m=2*n-1;/结点数结点数 typedef struct float weight;int parent,leftChild,rightChild;HTNode;typedef HTNode HuffmanTreem;霍夫曼树的定义建立霍夫曼树的算法建立霍夫曼树的算法void CreateHuffmanTree(HuffmanTree T,float fr )for(int i=0;i n;i+)Ti.weight=fri;for(i=0;i m;i+)Ti.parent=-1;Ti.leftChild=-1;Ti.rightChild=-1;for(i=n;i m;i+)int

43、 min1=min2=MaxNum;int pos1,pos2;for(int j=0;j i;j+)if(Tj.parent=-1)if(Tj.weight min1)pos2=pos1;min2=min1;pos1=j;min1=Tj.weight;else if(Tj.weight min2)pos2=j;min2=Tj.weight;Ti.leftChild=pos1;Ti.rightChild=pos2;Ti.weight=Tpos1.weight+Tpos2.weight;Tpos1.parent=Tpos2.parent=i;最佳判定树最佳判定树考试成绩分布表考试成绩分布表 0,

44、60)60,70)70,80)80,90)90,100)不及格不及格及格及格中中良良优优0.100.150.250.350.15判定树判定树60?70?80?90?0.100.150.250.350.15WPL=0.10*1+0.15*2+0.25*3+0.35*4+0.15*4 =3.15 最佳判定树最佳判定树60?70?80?90?0.100.150.250.350.15WPL=0.10*3+0.15*3+0.25*2+0.35*2+0.15*2 =0.3+0.45+0.5+0.7+0.3=2.25 霍夫曼编码霍夫曼编码主要用途是实现数据压缩。主要用途是实现数据压缩。设给出一段报文:设给出

45、一段报文:CAST CAST SAT AT A TASA 字符集合是字符集合是 C,A,S,T,各个字符出现,各个字符出现的频度的频度(次数次数)是是 W 2,7,4,5。若给每个字符以等长编码若给每个字符以等长编码 A:00 T:10 C:01 S:11则总编码长度为则总编码长度为(2+7+4+5)*2=36.若按各个字符出现的概率不同而给予不等若按各个字符出现的概率不同而给予不等长编码,可望减少总编码长度。长编码,可望减少总编码长度。各字符出现概率为各字符出现概率为 C:2/18,A:7/18,S:4/18,T:5/18,化整为化整为 2,7,4,5。以它们为各叶。以它们为各叶结点上的权值

46、结点上的权值,建立霍夫曼树。建立霍夫曼树。左分支赋左分支赋 0,右分支赋右分支赋 1,得霍夫曼编码,得霍夫曼编码(变长编码变长编码)。7254010011CAST CAST SAT AT A TASAA:0 T:10 C:110 S:111它的总它的总编码长度:编码长度:7*1+5*2+(2+4)*3=35。比等长编码的情形要短。比等长编码的情形要短。总编码长度正好等于霍夫总编码长度正好等于霍夫曼树的带权路径长度曼树的带权路径长度WPL。霍夫曼编码是一种霍夫曼编码是一种无前缀无前缀编码编码(都由叶结点组成都由叶结点组成,路径路径不会重复不会重复)。解码时不会混淆。解码时不会混淆。霍夫曼编码霍夫曼编码:A:0 T:10 C:110 S:111110011110 11001111011101001001001110等长编码等长编码:A:00 T:10 C:01 S:11010011100100111011001000100010001100霍夫曼编码树霍夫曼编码树0001112457

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 办公、行业 > 各类PPT课件(模板)
版权提示 | 免责声明

1,本文(数据结构-第六章-树与二叉树课件.ppt)为本站会员(晟晟文业)主动上传,163文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。
2,用户下载本文档,所消耗的文币(积分)将全额增加到上传者的账号。
3, 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(发送邮件至3464097650@qq.com或直接QQ联系客服),我们立即给予删除!


侵权处理QQ:3464097650--上传资料QQ:3464097650

【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。


163文库-Www.163Wenku.Com |网站地图|