构造哈夫曼树.docx

上传人:b****6 文档编号:7623428 上传时间:2023-01-25 格式:DOCX 页数:17 大小:106.99KB
下载 相关 举报
构造哈夫曼树.docx_第1页
第1页 / 共17页
构造哈夫曼树.docx_第2页
第2页 / 共17页
构造哈夫曼树.docx_第3页
第3页 / 共17页
构造哈夫曼树.docx_第4页
第4页 / 共17页
构造哈夫曼树.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

构造哈夫曼树.docx

《构造哈夫曼树.docx》由会员分享,可在线阅读,更多相关《构造哈夫曼树.docx(17页珍藏版)》请在冰豆网上搜索。

构造哈夫曼树.docx

构造哈夫曼树

西安文理学院软件学院

课程设计报告

设计名称:

数据结构课程设计

设计题目:

构造哈夫曼树的哈夫曼算法

学生学号:

1402120138

专业班级:

12级1班

学生姓名:

周欣

学生成绩:

指导教师(职称):

韩利凯(教授)

课题工作时间:

2014.6.16至2014.6.27

软件学院课程设计任务书

学生姓名

周欣

学号

1402120138

专业班级

1班

设计题目

构造哈夫曼树的哈夫曼算法

内容概要:

设计或开发环境:

MicrosoftVisualStudio2010

关键技术:

C语言

主要功能:

能求解出所构造的哈夫曼树的带权路径长度。

文献资料:

[1]严蔚敏吴伟民编.《数据结构(c语言版)》.清华大学出版社,2010.9

[2]韩利凯,李军.数据结构浙江大学出版社[M]2013.8

[3]谭浩强编.《C程序设计》.清华大学出版社2010.6

 

设计要求:

(1)可以使用实验工具的有关功能。

(2)要能演示构造过程。

(3)求解出所构造的哈夫曼树的带权路径长度。

工作期限:

设计工作自2014年6月16日至2014年6月27日止。

指导教师:

韩利凯院长:

日期:

2014年6月16日

软件学院课程设计进度安排表

学生姓名:

学号:

专业:

班级:

起止日期

内容

备注

6月16日~6月17日

下任务书;收集、阅读、整理相关参考文献,并进行归纳和概括总结,完成项目/任务背景介绍部分文字内容。

6月18日~11月20日

系统功能设计和模块设计、系统体系结构构建。

6月21日~6月24日

各功能模块编码实现,系统各功能模块调试与维护。

6月25日~6月26日

系统功能集成、系统调试与测试,按照模板要求撰写课程设计/项目设计报告。

6月27日

课程设计/项目设计分组答辩,提交课程设计/项目设计报告以及相关文档,进行成绩评定。

指导教师签名:

2014年6月16日

成绩评定表

学生姓名:

周欣学号:

1402120138专业:

软件工程班级:

1班

类别

合计

分值

各项分值

评分标准

实际得分

合计得分

平时表现

10

10

按时参加设计指导,无违反纪律情况。

完成情况

30

20

按设计任务书的要求完成了全部任务,能完整演示其设计内容,符合要求。

10

能对其设计内容进行详细、完整的介绍,并能就指导教师提出的问题进行正确的回答。

报告质量

35

10

报告文字通顺,内容翔实,论述充分、完整,立论正确,结构严谨合理;报告字数符合相关要求,工整规范,整齐划一。

5

课题背景介绍清楚,综述分析充分。

5

设计方案合理、可行,论证严谨,逻辑性强,具有说服力。

5

符号统一;图表完备、符合规范要求。

5

能对整个设计过程进行全面的总结,得出有价值的结论或结果。

5

参考文献数量在2篇以上,格式符合要求,在正文中正确引用。

答辩情况

25

10

在规定时间内能就所设计的内容进行阐述,言简意明,重点突出,论点正确,条理清晰。

15

在规定时间内能准确、完整、流利地回答教师所提出的问题。

 

总评成绩:

指导教师:

(签字)

日期:

2014年6月27日

摘要

摘要:

设计程序以实现构造哈夫曼树的哈夫曼算法,该程序的目的是求解出所构造的哈夫曼树的带权路径长度。

利用哈夫曼树的结构,求出指令的哈夫曼代码,同时求出叶子节点的带权路径长度。

依次输入五个值分别算出其权值,最后输出所构造的哈夫曼树的带权路径长度。

关键词:

数组;带权路径长度;结点.

 

目录

摘要v

目录I

第一章课题背景2

1.1课题背景2

1.11课题背景知识2

1.2课题目的与意义2

1.2.1课题的目的2

1.2.2课题意义2

第二章设计简介及设计方案论述3

2.1系统分析3

2.1.1功能需求3

2.1.2数据需求3

2.1.3系统需求3

2.2主要难点3

第三章详细设计4

3.1程序结构分析4

3.1.1图示4

3.1.2程序模块设计4

第四章设计结果及分析7

4.1程序运行结果7

4.1.1截图7

4.2运行结果分析7

4.2.1测试7

总结8

参考文献9

附录10

 

第一章课题背景

1.1课题背景

1.11课题背景知识

在实际生活和生产应用中,我们往往会遇到综合比较一系列的离散量的问题;比如说车站根据包裹的重量以及旅途的长短来确定携带行李的价格,或者我们根据一定的重量范围来给一箱铁球进行分类。

我们说在现实的分类中,每一类数据出现的概率不尽相同;这些数据出现的概率可以被看做哈夫曼树中叶子的权值。

为了获取最短的路径,也就是带权路径长度最短的二叉树,我们希望那些权值低的数据拥有相对较长的对根结点的路径长度。

1.2课题目的与意义

1.2.1课题的目的

本课题的目的是让同学们理解哈夫曼算法,并能利用自己已经学习的知识,去解决一些现实生活中出现的问题。

比如各个城市之间需要联网问题,利用哈夫曼树的相关知识就能对这一问题作出很好的解决。

1.2.2课题意义

一个好的算法可以更快的解决问题,所以平时在学习编程的时候应该着重理解一些基础的算法。

 

第二章设计简介及设计方案论述

2.1系统分析

2.1.1功能需求

(1)可以使用实验工具的有关功能。

(2)要能演示构造过程。

(3)求解出所构造的哈夫曼树的带权路径长度。

2.1.2数据需求

在输入过程中,首先要给定输入的数据,数据只能是数字,不能是字母或其他,不能连续输入数据,必须要求以换行分开要输入的数据。

2.1.3系统需求

系统必须安全可靠,不会出现无故死机状态,本程序较小,系统可以正常运行即可。

2.2主要难点

(1)构造哈夫曼树:

根据给定的权值构成二叉树集合,其中每棵二叉树中只有一个带权的根节点,其左右子树均为空;在二叉树集合中选取两棵根节点权值最小的树作为左右子树构造一棵新的二叉树,且新的二叉树的根节点的权值为其左、右子树上根节点的权值之和;在二叉树集合中删除这两棵树,并将得到的二叉树加入集合中;重复上述步骤,直至二叉树集合中只含一棵树为止。

(2)求带权路径长度:

先求每个叶子结点到树根之间的路径长度与该叶子结

点所带权值之积,在将所得之积求和。

 

第三章详细设计

3.1程序结构分析

3.1.1图示

 

 

3-1函数流程图

 

3.1.2程序模块设计

1)建立叶结点个数为n权值为weight的哈夫曼树haffTree

voidHaffman(intweight[],intn,HaffNodehaffTree[]){

intj,m1,m2,x1,x2;//哈夫曼树haffTree初始化。

n个叶结点的哈夫曼树共有2n-1个结点 

for(inti=0;i<2*n-1;i++)

{

if(i

elsehaffTree[i].weight=0;

haffTree[i].parent=0;

haffTree[i].flag=0;

haffTree[i].leftChild=-1;

haffTree[i].rightChild=-1;//构造哈夫曼树haffTree的n-1个非叶结点

}

2)将找出的两棵权值最小的子树合并为一棵子树

for(intk=0;k

{

m1=m2=MaxValue;

x1=x2=0;

for(j=0;j

{

if(haffTree[j].weight

{

m2=m1;

x2=x1;

m1=haffTree[j].weight;

x1=j;

}

elseif(haffTree[j].weight

{

m2=haffTree[j].weight;

x2=j;

}

}

3)由n个结点的哈夫曼树haffTree构造哈夫曼编码haffCode

voidHaffmanCode(HaffNodehaffTree[],intn,CodehaffCode[]){

Code*cd=newCode;

intchild,parent;//求n个叶结点的哈夫曼编码

for(inti=0;i

{

cd->start=n-1;//不等长编码的最后一位为n-1

cd->weight=haffTree[i].weight;//取得编码对应权值的字符

child=i;

parent=haffTree[child].parent;//由叶结点向上直到根结点

while(parent!

=0)

{

if(haffTree[parent].leftChild==child)

cd->bit[cd->start]=0;//左孩子结点编码0

else

cd->bit[cd->start]=1;//右孩子结点编码1

cd->start--;

child=parent;

parent=haffTree[child].parent;

}//保存叶结点的编码和不等长编码的起始位

for(intj=cd->start+1;j

haffCode[i].bit[j]=cd->bit[j];

haffCode[i].start=cd->start;

haffCode[i].weight=cd->weight;//保存编码对应的权值

}

}

 

第四章设计结果及分析

4.1程序运行结果

4.1.1截图

4.2运行结果分析

该运行结果为输入了五个结点的权值之后所得到的哈夫曼编码和所得到的带权路径长度,通过本次试验我更好地了解了哈夫曼树的结构,知道了最优二树的优点与实际应用,学会了怎么求哈夫曼树的带权路径长度。

4.2.1测试

软件测试是软件生存期中的一个重要阶段,是软件质量保证的关键步骤从用户的角度来看,普遍希望通过软件测试暴露软件中隐藏的错误和缺陷,所以软件测试应该是“为了发现错误而执行程序的过程”。

或者说,软件测试应该根据软件开发各阶段的规格说明和程序的内部结构而精心设计一批测试用例(即输入数据及其预期的输出结果),并利用这些测试用例去运行程序,以发现程序错误或缺陷。

过度测试则会浪费许多宝贵的资源。

到测试后期,即使找到了错误,然而付出了过高的代价。

总结

在我自己课程设计中,就在编写好源代码后的调试中出现了不少的错误,遇到了很多麻烦及困难,我的调试及其中的错误和我最终找出错误,修改为正确的能够执行的程序中,通过分析,我学到了:

在定义头文件时可多不可少,即我们可多写些头文件,肯定不会出错,但是若没有定义所引用的相关头文件,必定调试不通过;在这次课程设计中我学习了很多在上课没懂的知识,并对求哈夫曼树的算法有了更加深刻的了解,更巩固了课堂中学习有关于哈夫曼编树的知识,真正学会了一种算法。

当求解一个算法时,不是拿到问题就不加思索地做,而是首先要先对它有个大概的了解,接着再详细地分析每一步怎么做,无论自己以前是否有处理过相似的问题,只要按照以上的步骤,必定会顺利地做出来。

通过本次数据结构的课程设计,虽然程序运行结果基本正确,能实现实验要求的功能,但也存在不足的地方,如运行界面不美观,程序语句不精练,有些地方可以更加简单等等。

这些都需要我在以后的实验中着重注意并加以学习,另外,这次实验编程我花的时间较短,因为学期末复习工作比较忙,所以本程序还有一些不足之处。

 

参考文献

[1]严蔚敏吴伟民编.《数据结构(c语言版)》.清华大学出版社,2010.9

[2]韩利凯,李军.数据结构浙江大学出版社[M]2013.8

[3]谭浩强编.《C程序设计》.清华大学出版社2010.6

[4]唐国民,王国均.数据结构(C语言版)[M].北京:

清华大学出版社.

[5]王路明.C语言程序设计教程[M].北京:

北京邮电大学出版社,2005年5月.

[6]谭浩强.C++程序设计[M].北京:

清华大学出版社.2004.

[7]范策.算法与数据结构(C语言版)[M].北京:

机械工业出版社,2004.

[8]詹春华,杨沙.C语言程序设计教程[M].科学出版社,2011.8.

 

附录

#include

#include

#include

constintMaxValue=1000;//初始设定的权值最大值

constintMaxBit=4;//初始设定的最大编码位数

constintMaxN=10;//初始设定的最大结点个数

structHaffNode//哈夫曼树的结点结构

{

intweight;//权值

intflag;//标记

intparent;//双亲结点下标

intleftChild;//左孩子下标

intrightChild;//右孩子下标

};

structCode//存放哈夫曼编码的数据元素结构

{

intbit[MaxN];//数组

intstart;//编码的起始下标

intweight;//字符的权值

};

voidHaffman(intweight[],intn,HaffNodehaffTree[])//建立叶结点个数为n权值为weight的哈夫曼树haffTree

{

intj,m1,m2,x1,x2;//哈夫曼树haffTree初始化。

n个叶结点的哈夫曼树共有2n-1个结点 

for(inti=0;i<2*n-1;i++)

{

if(i

elsehaffTree[i].weight=0;

haffTree[i].parent=0;

haffTree[i].flag=0;

haffTree[i].leftChild=-1;

haffTree[i].rightChild=-1;//构造哈夫曼树haffTree的n-1个非叶结点

}

for(intk=0;k

{

m1=m2=MaxValue;

x1=x2=0;

for(j=0;j

{

if(haffTree[j].weight

{

m2=m1;

x2=x1;

m1=haffTree[j].weight;

x1=j;

}

elseif(haffTree[j].weight

{

m2=haffTree[j].weight;

x2=j;

}

}//将找出的两棵权值最小的子树合并为一棵子树

haffTree[x1].parent=n+k;

haffTree[x2].parent=n+k;

haffTree[x1].flag=1;

haffTree[x2].flag=1;

haffTree[n+k].weight=haffTree[x1].weight+haffTree[x2].weight;

haffTree[n+k].leftChild=x1;

haffTree[n+k].rightChild=x2;

}

}

voidHaffmanCode(HaffNodehaffTree[],intn,CodehaffCode[])//由n个结点的哈夫曼树haffTree构造哈夫曼编码haffCode

{

Code*cd=newCode;

intchild,parent;//求n个叶结点的哈夫曼编码

for(inti=0;i

{

cd->start=n-1;//不等长编码的最后一位为n-1

cd->weight=haffTree[i].weight;//取得编码对应权值的字符

child=i;

parent=haffTree[child].parent;//由叶结点向上直到根结点

while(parent!

=0)

{

if(haffTree[parent].leftChild==child)

cd->bit[cd->start]=1;//左孩子结点编码0

else

cd->bit[cd->start]=0;//右孩子结点编码1

cd->start--;

child=parent;

parent=haffTree[child].parent;

}//保存叶结点的编码和不等长编码的起始位

for(intj=cd->start+1;j

haffCode[i].bit[j]=cd->bit[j];

haffCode[i].start=cd->start;

haffCode[i].weight=cd->weight;//保存编码对应的权值

}

}

intmain()

{

cout<<"\n";

cout<<""<<"请依次输入各权值";

inti,j,n=5,sum=0,l=0;

intweight[5];

for(intk=0;k<5;k++){

cin>>weight[k];

}

HaffNode*myHaffTree=newHaffNode[2*n+1];

Code*myHaffCode=newCode[n];

if(n>MaxN)

{

cout<<"定义的n越界,修改MaxN!

"<

exit(0);

}

Haffman(weight,n,myHaffTree);

HaffmanCode(myHaffTree,n,myHaffCode);//输出每个叶结点的哈夫曼编码

for(i=0;i

{

cout<<"Weight="<

for(j=myHaffCode[i].start+1;j

cout<

sum=sum+l*myHaffCode[i].weight;

l=0;

/*if(myHaffCode[i].bit[j]/10>=0&&myHaffCode[i].*bit[j]/10<1){l=1;sum=sum+myHaffCode[i].weight*l;}

elseif(myHaffCode[i].bit[j]/10>=1&&myHaffCode[i].bit[j]/10<10){l=2;sum=sum+myHaffCode[i].weight*l;}

elseif(myHaffCode[i].bit[j]/10>=10&&myHaffCode[i].bit[j]/10<100){l=3;sum=sum+myHaffCode[i].weight*l;}

elseif(myHaffCode[i].bit[j]/10>=100&&myHaffCode[i].bit[j]/10<1000){l=4;sum=sum+myHaffCode[i].weight*l;}

elseif(myHaffCode[i].bit[j]/10>=1000&&myHaffCode[i].bit[j]/10<10000){l=5;sum=sum+myHaffCode[i].weight*l;}

else{}*/

}

cout<<"带权路径长度="<

return0;

}

 

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

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1