哈夫曼树及其应用教案
数据结构课程设计哈夫曼

数据结构课程设计哈夫曼一、课程目标知识目标:1. 理解哈夫曼编码的基本原理和构建方法;2. 掌握哈夫曼树的结构特点及其应用;3. 学会运用哈夫曼编码进行数据压缩,并了解其优缺点。
技能目标:1. 能够运用所学知识构建哈夫曼树并进行编码;2. 能够分析给定数据集的最优哈夫曼编码方案;3. 能够运用哈夫曼编码解决实际问题,如文件压缩与解压。
情感态度价值观目标:1. 培养学生对数据结构在计算机科学中重要性的认识,激发对数据结构学习的兴趣;2. 培养学生的团队合作意识,学会在团队中发挥个人优势,共同解决问题;3. 培养学生严谨、细致的学术态度,养成良好的编程习惯。
课程性质分析:本课程为高中信息技术学科的数据结构部分,旨在让学生了解并掌握常用的数据结构及其应用。
哈夫曼编码作为数据结构中的一种重要应用,具有很高的实用价值。
学生特点分析:高中学生已经具备了一定的逻辑思维能力,能够理解抽象的概念,但实践经验不足,需要通过具体的案例和动手操作来加深理解。
教学要求:1. 理论与实践相结合,注重培养学生的动手能力;2. 以学生为主体,鼓励学生主动探究、合作学习;3. 注重培养学生的创新能力和解决问题的能力。
二、教学内容1. 引入:回顾树的基本概念,为新课哈夫曼树做好知识铺垫。
教材章节:第二章 树与二叉树2. 哈夫曼编码原理:- 哈夫曼编码的基本思想与原理- 哈夫曼树的构建过程教材章节:第二章 树与二叉树,第五节 哈夫曼编码3. 哈夫曼树的构建方法:- 构建哈夫曼树的步骤- 哈夫曼编码的生成方法教材章节:第二章 树与二叉树,第五节 哈夫曼编码4. 哈夫曼编码的应用:- 文件压缩与解压的原理- 哈夫曼编码在数据压缩中的应用案例教材章节:第二章 树与二叉树,第五节 哈夫曼编码及应用5. 实践操作:- 动手编写程序构建哈夫曼树并进行编码- 分析实际数据集,设计最优哈夫曼编码方案教材章节:第二章 树与二叉树,第五节 哈夫曼编码实践6. 总结与拓展:- 总结哈夫曼编码的特点及其在数据压缩中的应用优势- 探讨哈夫曼编码在其他领域的拓展应用教材章节:第二章 树与二叉树,第五节 哈夫曼编码拓展与应用教学内容安排与进度:1. 引言与回顾:1课时2. 哈夫曼编码原理与构建方法:2课时3. 哈夫曼编码应用与实践操作:2课时4. 总结与拓展:1课时总计:6课时三、教学方法1. 讲授法:- 在讲解哈夫曼编码的基本原理、构建方法及应用场景时,采用讲授法进行知识传授,使学生在短时间内掌握关键概念和理论。
电报哈夫曼树课程设计

电报哈夫曼树课程设计一、课程目标知识目标:1. 学生能理解哈夫曼树的定义及其在数据压缩中的应用。
2. 学生能掌握哈夫曼编码的构建过程,并运用其进行基本的编码和解码操作。
3. 学生能了解哈夫曼树的基本性质,如最优二叉树、路径长度最短等。
技能目标:1. 学生能够运用所学知识解决实际问题,如使用哈夫曼编码进行文件压缩和解压缩。
2. 学生通过实际操作,培养解决问题的能力,提高逻辑思维能力。
3. 学生能够运用数学方法,对哈夫曼树进行证明和分析。
情感态度价值观目标:1. 学生培养对数据结构和算法的兴趣,认识到其在实际生活中的重要性。
2. 学生通过合作学习,培养团队协作精神,提高沟通与表达能力。
3. 学生在学习过程中,培养面对困难勇于挑战的精神,增强自信心。
课程性质:本课程为信息技术或计算机科学相关学科的课程,旨在通过哈夫曼树的学习,让学生掌握数据压缩的基本原理和方法。
学生特点:考虑到学生所在年级的特点,课程设计将结合具体实例,由浅入深地进行教学,使学生易于理解和掌握。
教学要求:教学过程中,注重理论与实践相结合,强调学生的实际操作能力。
同时,注重培养学生的逻辑思维能力和团队协作能力,提高学生的综合素质。
通过分解课程目标,为后续教学设计和评估提供明确的方向。
二、教学内容1. 引入:介绍数据压缩的概念及其在生活中的应用,引导学生思考数据压缩的必要性。
2. 哈夫曼树基本概念:讲解哈夫曼树的定义、性质和应用场景,使学生了解哈夫曼树在数据压缩中的重要性。
- 理解哈夫曼树的构建过程- 掌握哈夫曼树的路径长度和最优二叉树的概念3. 哈夫曼编码:详细讲解哈夫曼编码的构建方法,以及如何利用哈夫曼编码进行数据压缩和解压缩。
- 学习哈夫曼编码的构建步骤- 实践哈夫曼编码的应用案例4. 哈夫曼树的分析与证明:分析哈夫曼树的基本性质,并对最优二叉树进行数学证明。
- 掌握哈夫曼树的数学证明方法- 理解哈夫曼树在数据压缩中的优势5. 实践操作:结合教材实例,让学生动手实践,加深对哈夫曼树及其编码方法的理解。
数据结构35-Huffman树及其应用

if(ht[j].w < m && ht[j].parent==0)
{ n=m; y=x; m=ht[j].w; x=j; }
/* 选取最小的权 */
else if(ht[j].w <n && ht[j].parent==0) /* 选取次小的权 */
{ n=ht[j].w; y=j; }
/* 准备合并两棵二叉树 */
c=i; f=ht[c].parent;
while (f)
{ if (ht[f].lchild=c) cd.bits[cd.start]=0; /* 左分枝赋0 */
else cd.bits[cd.start]=1; cd.start--; c=f; f=ht[f].parent; /* 右分枝赋1 */
数
据
结
构
第三十五课 Huffman树及其应用
第二十七课 Huffman树及其应用
本课主题: Huffman树及其应用 教学目的: 掌握Huffman树的概念及其应用 教学重点:掌握Huffman编码 教学难点:掌握Huffman编码
授课内容:
一﹑最优二叉树(哈夫曼树----带权路径长 度最短的树)
⑥ 哈夫曼树(最优二叉树)
带权路径长度之和最小的二叉树称为哈夫曼树(最 优二叉树)
⑦ 哈夫曼编码 在哈夫曼树上,左分枝为0,右分枝为1,从根结点 开始,直到叶子结点所组成的编码序列,称为叶子结 点的哈夫将百分制转为五级记分制的例子。说明哈夫曼树判定次
数最少的树(即带权路径长度最短、最节省计算时
typedef struct
{ unsigned int w;
unsigned int parent,lchild,rchild; } HTNode,*HTree; typedef struct { unsigned int bits[n]; unsigned int start; } HTCode;
哈夫曼树及应用

常熟理工学院微课教学比赛教学设计1、课程基本信息课程名称:哈夫曼树及应用所属课程:数据结构与算法课程所属专业:软件工程适用专业:计算机类选用教材:严蔚敏,吴伟明编著《数据结构(C语言版)》北京:清华大学出版社,2007主讲人:周思林时长:15分钟所属学校:常熟理工学院所属院系:计算机科学与工程学院2.教学背景《数据结构与算法》课程是计算机类专业的学科基础课程,本节微课“哈夫曼树及应用”属于数据结构课程中的“树与二叉树”章节中的重点及难点。
2.1《数据结构与算法》课程简介及特点《数据结构与算法》课程是计算机类专业的学科基础课程,同时也是计算机类专业的核心课程。
课程的主要目标是使学生理解和掌握基本数据结构的概念、经典算法的思想及实现方法,具备为应用所涉及的数据选择适当的逻辑结构、存储结构及其相应的操作算法的能力。
数据结构与算法课程的学习也是复杂程序设计的训练过程,通过算法设计和实践,培养学生的数据抽象和复杂程序设计能力。
《数据结构与算法》课程由线性结构、树形结构、图状结构三种逻辑结构和查找、排序算法为主体,结合应用型本科院校特点,通过实践理解和掌握基本数据结构与算法,在实践中提高学生的专业素养和专业技能。
2.2本节微课课程特点“树与二叉树——哈夫曼树及应用”是《数据结构与算法》课程中第六章“树与二叉树”的核心内容之一,同时也是该章节的教学难点。
本节微课采用案例驱动法进行教学,调动学生的学习积极性,引导学生发现问题、思考问题、解决问题,利用形象的多媒体动画展示案例的执行过程,将哈夫曼树及编码复杂的程序结构趣味化、形象化。
由发送报文问题引入课程,循序渐进的介绍哈夫曼树的概念、逻辑特性、存储结构和算法实现,使学生掌握哈夫曼树及编码的基本概念和算法,提升学生的程序设计及逻辑思维能力。
3.教学设计3.1教学目的通过本节微课的学习,培养学生以下几个方面的能力:(1)理解哈夫曼树的应用范围和场景,并能灵活运用;(2)掌握哈夫曼树及编码的概念、求解算法基本思想,针对实例,能构造哈夫曼树,求解哈夫曼编码;(3)掌握哈夫曼树的存储结构,理解静态三叉链表结构;(4)掌握哈夫曼树及编码的求解算法,并能在实验中实现并验证算法(难点);根据学生理论基础及程序编码能力,本微课教学目标分为三个水平:合格、中等、优秀,具体标准如下:合格水平:熟练掌握哈夫曼树及编码的基本概念,能构造哈夫曼树,求解哈夫曼编码。
数据结构哈夫曼树的构造及其应用课程设计实验报告

目录第一章哈夫曼树的基本术语 (1)1.1路径和路径长度 (1)1.2树的带权路径长度 (1)1.3哈夫曼树的定义 (1)第二章哈夫曼树的构造 (2)2.1哈夫曼树的构造 (2)第三章哈夫曼树的存储结构及哈夫曼算法的实现 (3)3.1哈夫曼树的存储结构 (3)3.2 哈夫曼算法的简要描述 (3)第四章哈夫曼树的应用 (5)4.1哈夫曼编码 (5)4.2求哈夫曼编码的算法 (5)4.21思想方法 (5)4.22字符集编码的存储结构及其算法描述 (6)4.3哈夫曼树和编码程序实现: (6)4.4程序运行结果: (9)心得体会 (10)参考文献 (10)第一章哈夫曼树的基本术语1.1路径和路径长度在一棵树中,从一个结点往下可以达到的孩子或子孙结点之间的通路,称为路径。
通路中分支的数目称为路径长度。
若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1。
1.2结点的权及带权路径长度若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。
结点的带权路径长度为:从根结点到该结点之间的路径长度与该结点的权的乘积。
1.2树的带权路径长度树的带权路径长度(Weighted Path Length of Tree):也称为树的代价,定义为树中所有叶结点的带权路径长度之和,通常记为:其中:n表示叶子结点的数目wi和li分别表示叶结点ki的权值和根到结点ki之间的路径长度。
1.3哈夫曼树的定义在权为wl ,w2,…,wn的n个叶子所构成的所有二叉树中,带权路径长度最小(即代价最小)的二叉树称为最优二叉树或哈夫曼树。
[例]给定4个叶子结点a,b,c和d,分别带权7,5,2和4。
构造如下图所示的三棵二叉树(还有许多棵),它们的带权路径长度分别为:(a)WPL=7*2+5*2+2*2+4*2=36(b)WPL=7*3+5*3+2*1+4*2=4(c)WPL=7*1+5*2+2*3+4*3=35其中(c)树的WPL最小,可以验证,它就是哈夫曼树。
哈夫曼树

实验4.2 最优二叉树(哈夫曼树)一、实验的目的要求1、了解树和哈夫曼树的特性,以及它们在实际问题中的应用。
2、掌握树和哈夫曼树的实现方法以及它们的基本操作,学会运用树和二叉树来解决问题。
二、实验的主要内容1、请设计一个算法,对于给定的n个结点的权值,建立一棵哈夫曼树。
具体要求如下:①算法输入:n个结点的权值。
②算法输出:哈夫曼树,打印出哈夫曼树的所有的结点序号、双亲结点、左孩子、右孩子和权值。
③测试数据:⑴设结点数n=7,权值分别为7、5、2、3、8、10、20;⑵设结点数n=8,权值分别为7、19、2、6、32、3、21、10。
三、解题思路建立哈夫曼树,然后对哈夫曼树进行操作。
四、原程序清单//c++程序#include<iostream>#include<string>#include<stdlib.h>using namespace std;#define MAXVAL 10000000 //定义一个足够大的数,方便之后的操作typedef int datatype;typedef struct//定义哈夫曼树结构体类型{double weight; //结点的权值int num;datatype lchild,rchild,parent; //结点的左、右孩子指针和父指针} htree;htree tree[100]; //定义全局变量,方便操作int n,m,flag=1; //n表示预处理的结点数,m表示处理的结点总数void create() //建立哈夫曼树的函数{int i,j,p1,p2; //i,j用于循环语句,p1、p2用于记录操作结果double small1,small2,w; //操作的中间变量cout<<"\n 请输入预处理的结点数:";cin>>n;m=2*n-1;if(n<=0){printf("\n*****************************************************\n");printf(" 这是一棵空树\n");printf("*****************************************************\n");return;}printf("\n*****************************************************\n");printf(" 请依次输入个结点的权值(各权值以空格隔开)\n");printf("*****************************************************\n");for(i=1;i<=n;i++) //为n个结点初始化{cin>>w;tree[i].weight=w;tree[i].num=i;tree[i].parent=0;tree[i].lchild=0;tree[i].rchild=0;}for(i=n+1;i<=m;i++){p1=0;p2=0;small1=MAXVAL;small2=MAXVAL;for(j=1;j<=i-1;j++)if(tree[j].parent==0){if(tree[j].weight<small1){small2=small1;small1=tree[j].weight;p2=p1;p1=j;}else if(tree[j].weight<small2){small2=tree[j].weight;p2=j;}}tree[p1].parent=i;tree[p2].parent=i;tree[i].num=i;tree[i].parent=0;tree[i].lchild=p1;tree[i].rchild=p2;tree[i].weight=tree[p1].weight+tree[p2].weight;}printf("\n*****************************************************\n");printf(" 哈夫曼树初始化完毕\n");printf("*****************************************************\n"); }void print1(htree t) //用于输出哈夫曼树的先序序列{cout<<'\t'<<'\t'<<t.num<<'\t'<<t.weight<<endl;if(t.lchild!=0)print1(tree[t.lchild]);if(t.rchild!=0)print1(tree[t.rchild]);}void print2(htree t) //用于输出哈夫曼树的中序序列{if(t.lchild!=0)print2(tree[t.lchild]);cout<<'\t'<<'\t'<<t.num<<'\t'<<t.weight<<endl;if(t.rchild!=0)print2(tree[t.rchild]);}void print3(htree t) //用于输出哈夫曼树的中序序列{if(t.lchild!=0)print3(tree[t.lchild]);if(t.rchild!=0)print3(tree[t.rchild]);cout<<'\t'<<'\t'<<t.num<<'\t'<<t.weight<<endl;}int high(htree t) //计算哈夫曼树的高度{int a,b;if(t.lchild==0&&t.rchild==0)return 1;a=high(tree[t.lchild])+1;b=high(tree[t.rchild])+1;if(a>b)return a;return b;}int main(){string i,j;while(1){printf("\n*****************************************************\n");printf(" 欢迎使用菜单驱动程序\n");printf("*****************************************************\n");if(flag==1){printf(" 1.初始化哈夫曼树\n"); //第一级菜单printf(" 2.清屏\n");printf(" 3.结束操作\n");printf("\n 请选择您要的操作:");cin>>i;if(i=="1"){create();flag=0;}else if(i=="2")system("cls");else if(i=="3"){printf("\n*****************************************************\n");printf(" 谢谢使用,再见\n");printf("*****************************************************\n");return 1;}else{printf("\n*****************************************************\n");printf(" 操作错误\n");printf("*****************************************************\n");}continue;}printf(" 1.重新初始化哈夫曼树\n"); //第二级菜单printf(" 2.输出哈夫曼树的高度\n");printf(" 3.输出哈夫曼树的叶子结点的个数\n");printf(" 4.输出哈夫曼树\n");printf(" 5.清屏\n");printf(" 0.结束操作\n");printf("\n 请选择您要的操作:");cin>>i;if(i=="1")create();else if(i=="2"){if(n==0){printf("\n*****************************************************\n");printf(" 这是一棵空树,高度为0\n");printf("*****************************************************\n");}else{printf("\n*****************************************************\n");printf(" 该树的高度为%d\n",high(tree[m]));printf("*****************************************************\n");}}else if(i=="3"){if(n==0){printf("\n*****************************************************\n");printf(" 这是一棵空树,叶子结点的个数为0\n");printf("*****************************************************\n");}else{printf("\n*****************************************************\n");printf(" 该树的叶子结点的个数为%d\n",n);printf("*****************************************************\n");}}else if(i=="4"){if(n==0){printf("\n*****************************************************\n");printf(" 这是一棵空树\n");printf("*****************************************************\n");continue;}while(1){printf("\n*****************************************************\n");printf(" 欢迎使用菜单驱动程序\n");printf("*****************************************************\n");printf(" 1.输出哈夫曼树的先序序列\n"); //第三级菜单printf(" 2.输出哈夫曼树的中序序列\n");printf(" 3.输出哈夫曼树的后序序列\n");printf(" 4.返回上层\n");printf(" 5.清屏\n");printf(" 0.结束操作\n");printf("\n 请输入您要的操作:");fflush(stdin);cin>>j;if(j=="1"){printf("\n*****************************************************\n");printf(" 哈夫曼树的先序序列如下(左为结点序号,右为为结点权值)\n");printf("*****************************************************\n");print1(tree[m]);}else if(j=="2"){printf("\n*****************************************************\n");printf(" 哈夫曼树的中序序列如下(左为结点序号,右为为结点权值)\n");printf("*****************************************************\n");print2(tree[m]);}else if(j=="3"){printf("\n*****************************************************\n");printf(" 哈夫曼树的后序序列如下(左为结点序号,右为为结点权值)\n");printf("*****************************************************\n");print3(tree[m]);}else if(j=="4")break;else if(j=="5")system("cls");else if(j=="0"){printf("\n*****************************************************\n");printf(" 谢谢使用,再见\n");printf("*****************************************************\n");return 1;}else{printf("\n*****************************************************\n");printf(" 操作错误\n");printf("*****************************************************\n");}}}else if(i=="5")system("cls");else if(i=="0"){printf("\n*****************************************************\n");printf(" 谢谢使用,再见\n");printf("*****************************************************\n");return 1;}else{printf("\n*****************************************************\n");printf(" 操作错误\n");printf("*****************************************************\n");}}}五. 调试小结(1).遇到的问题及解决方法1.输出函数中没有提示语句;2.p1,p2赋值错误;(2). 算法复杂度分析本实验纯属一般操作。
哈夫曼树及其应用

****课程设计报告题目:哈夫曼树及其应用学生姓名:何昆学号:0418班级:1121804指导教师:张军2021年 1 月10 日目录一、需求分析说明 (3)1.课程设计目的 (3)2.课程设计题目 (3)3.程序功能及需求说明 (3)二、整体设计 (4)1.哈夫曼树成立 (4)2.哈夫曼编码 (4)3.哈夫曼译码 (4)三、详细设计 (5)1. 算法设计 (5)2. 类设计 (5)四、实现部份 (6)五、程序测试 (9)六、总结 (10)一、需求分析说明1、课程设计目的本课程设计的目的考察学生对常见数据结构及相关算法的综合应用能力,达到理论与实际应用相结合,使同窗们能够依照数据对象的特性,学会数据组织的方式,解决实际问题中数据的合理存储表示,并依照相应的存储结构设计效率较高的算法实现对问题的求解;通过这次课程设计进一步培育学生良好的程序设计技术和分析问题解决问题的能力。
二、课程设计题目:哈夫曼树及其应用(1).设计目的:熟悉树的各类存储结构及其特点及把握成立哈夫曼树和哈夫曼编码的方式及带权途径长度的计算。
(2).设计内容:欲发一封内容为AABBCAB ……(共长 100 字符,其中:A 、B 、C 、D 、E 、F别离有7 、9 、12 、22 、23、27个)的电报报文,实现哈夫曼编码和译码。
(3).设计要求:分析系统需求。
成立哈夫曼树。
进行哈夫曼编码,并求出平均编码长度。
译码,对编码好的内容进行译码。
3、程序功能及需求说明功能:编码,编码长度,译码要实现编码译码等功能,必需先成立一个哈夫曼树,编码长度、译码又通过编码求得。
那个地址通过别离创建结点类(tree)和编码类(codetype),子函数有哈夫曼树成立(creathuffmantree),哈夫曼编码(arrangecode),哈夫曼译码(transcode),最后通过主函数挪用执行。
2.哈夫曼树编码(途径往左为0,往右为1)带权途径长度:WPL=7*4+9*4+12*3+22*2+23*2+27*2=244平均编码长度为:4+5+5+6+6+7=33(1).成立哈夫曼树的算法:概念各节点类型其中应包括两类数据一是权值域weight;一是指针域而指针域中应该包括指向左右小孩和指向双亲的指针那个地址别离用lchild、rdhild 和parent来表示,在实际构造中由于是叶子节点来构造新的根节点其构造进程中仅与叶子节点的权重有关而与其数据域无关因此构造进程中不用考虑其数值域,而且在链表中从叶子开始寄存,让后不断的将两颗最小权值的子树归并为一颗权值为其和的较大的子树,慢慢生成各自内部节点直到树根。
哈夫曼树的应用数据结构课程设计

《数据结构》课程设计报告题目:哈夫曼树应用学生姓名:谢辉学号: 201317010201专业班级:计科13102同组姓名:赵丽娜指导教师:徐晓蓉设计时间:2014年下学期第18周目录一、需求分析 (2)1. 分析问题 (2)2. 确定解决方案 (2)3. 输入的形式和输入值的范围 (3)4.输出的形式 (3)5.程序所能达到的功能 (3)二、概要设计 (4)1. 主程序的流程图: (4)2.程序中数据类型的定义: (4)3.各程序模块之间的层次(调用)关系: (4)三、详细设计 (5)1.哈夫曼树存储及类的定义: (5)2.哈夫曼树的基本操作: (6)3.主函数 (7)1. 测试数据及其输出结果: (9)2. 调试过程中遇到的问题及解决办法: (13)五、总结 (14)七、致谢 (14)八、附录 (14)一、需求分析1.分析问题利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。
但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。
对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。
为这样的信息收发站写一个哈夫曼码的编/译码系统。
2.确定解决方案设计建立带权的哈夫曼树,确定哈夫曼树的类与成员函数,以及各函数之间的调用关系,采用动态数组的存储结构存储所需要的数据,通过不同的函数来实现编码,译码以及打印二进制编码、哈夫曼树,把不同的数据存入不同的txt文件中,通过主函数调用来实现功能检测。
3.输入的形式和输入值的范围手动或者从文本中读入数据的形式初始化哈夫曼树,从键盘中或者文件中读入数据,以字母A-Z代表结点,以自然数代表权值,字符串提示使用者所要执行的操作。
4.输出的形式在显示器界面上或者以文本的形式来实现程序调试的输出。
5.程序所能达到的功能(1)I:初始化(Initialization)。
从终端读入字符集大小n,以及n个字符和n 个权值,建立哈夫曼树,并将它存于文件hfmTree中。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
授课时间11.9 第17 次课
学院审核意见
该教案教学目的明确,教学内容先进,课时设计合理,重点那点把握准确,符合信
息学院教学要求,同意实施。
学院负责人签字刘方爱
年月日
哈夫曼树的构造过程中应注意的问题
2007-07-18
哈夫曼树(Huffman树)是带权路径长度最小的二叉树。
根据哈夫曼树的定义,一棵二叉树要使其带权路径长度最小,必须使权值越大的叶子结点越靠近根结点,而权值越小的叶子结点越远离根结点。
哈夫曼依据这一特点提出了哈夫曼算法,其基本思想是:
⑴初始化:由给定的n个权值{w1,w2,…,wn}构造n棵只有一个根结点的二叉树,从而得到一个二叉树集合F={T1,T2,…,Tn};
⑵选取与合并:在F中选取根结点的权值最小的两棵二叉树分别作为左、右子树构造一棵新的二叉树,这棵新二叉树的根结点的权值为其左、右子树根结点权值之和;
⑶删除与加入:在集合F中删除作为左、右子树的两棵二叉树,并将新建立的二叉树加入到集合F中;
⑷重复⑵、⑶两步,当集合F中只剩下一棵二叉树时,这棵二叉树便是哈夫曼树。
通过上述Huffman树的构造过程,我们可以得到如下要点:
⑴当有n个权值(相应的Huffman树中有n个叶子),共需合并n-1次;
⑵每合并一次产生一个分支结点,经过n-1次合并后得到的Huffman树中共有2n-1个结点,其中有n-1个分支结点;
⑶在Huffman树中只有度为0(叶子结点)和度为2(分支结点)的结点,不存在度为1的结点;
⑷算法要求选取根结点权值最小的两棵二叉树作为左右子树构造一棵新的二叉树,但并没有要求哪一棵作左子树,哪一棵作右子树,所以左右子树的顺序是任意的;
⑸对同一组权值可以构造出不同的huffman树,但是他们的带权路径长度相同。
在建立Huffman树的过程中有以下三种常见的错误:
⑴在合并中不是选取根结点权值最小的两棵二叉树(包括已合并的和未合并的),而是选取未合并的根结点权值最小的一棵二叉树与已经合并的二叉树合并,如图5-10所示。
⑵每次都是在未合并的二叉树中选取根结点的权值最小的两棵子树,如图5-11所示。
⑶有时没有严格按照哈夫曼算法也构造出带权路径长度与哈夫曼树相同的二叉树,但那只是巧合,没有规律性,而没有规律性的解法不利于用计算机进行处理。
哈夫曼树就是最优二叉查找树,对于带权的二叉树的查找,权值最大的离根结点最近,按照这一思路,带权结点所构成的所有二叉树中带权路径长度WPL最小的二叉树,将其应用于计算机通信中数据编码技术可大大缩短电文代码的长度。
数据编码技术在计算机数字通信中一直占据着重要的地位。
而在数字通信过程中,往往存在问题:信息传递的速度和所传递信息的可靠性这对不可调和的矛盾,所传递的数据编码的长度和数据译码容易产生的二义性等。
以上问题,使得数据编码技术的优劣在很大程度上影响着通信的质量。