哈夫曼树课程设计.docx

上传人:b****6 文档编号:7982184 上传时间:2023-01-27 格式:DOCX 页数:18 大小:107.16KB
下载 相关 举报
哈夫曼树课程设计.docx_第1页
第1页 / 共18页
哈夫曼树课程设计.docx_第2页
第2页 / 共18页
哈夫曼树课程设计.docx_第3页
第3页 / 共18页
哈夫曼树课程设计.docx_第4页
第4页 / 共18页
哈夫曼树课程设计.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

哈夫曼树课程设计.docx

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

哈夫曼树课程设计.docx

哈夫曼树课程设计

中南林业科技大学

课程设计报告

设计名称:

数据结构课程设计

姓名:

王昆学号:

20094282

专业班级:

2009级软件工程

系(院):

计算机与信息工程学院

设计时间:

2010~2011学年第二学期

设计地点:

电子信息楼机房

成绩:

指导教师评语:

 

签名:

年月日

1.课程设计目的

1、训练学生灵活应用所学数据结构知识,独立完成问题分析,结合数据结构理论知识,编写程序求解指定问题。

2.初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能;

3.提高综合运用所学的理论知识和方法独立分析和解决问题的能力;

4.训练用系统的观点和软件开发一般规范进行软件开发,巩固、深化学生的理论知识,提高编程水平,并在此过程中培养他们严谨的科学态度和良好的工作作风。

2.课程设计任务与要求:

任务

.哈夫曼树应用

功能:

(1)从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树并将它存于文件hfmTree中.将已在内存中的哈夫曼树

以直观的方式(比如树)显示在终端上;

(2)利用已经建好的哈夫曼树(如不在内存,则从文件htmTree中读入),对文件ToBeTran中的正文进行编码,然后将结果存

入文件CodeFile中,并输出结果,将文件CodeFile以紧凑格式先是在终端上,每行50个代码。

同时将此字符形式的

编码文件写入文件CodePrint中。

(3)利用已建好的哈夫曼树将文件CodeFile中的代码进行译码,结果存入文件TextFile中,并输出结果。

分步实施:

1)初步完成总体设计,搭好框架,确定人机对话的界面,确定函数个数;

2)完成最低要求:

完成功能1;

3)进一步要求:

完成功能2和3。

有兴趣的同学可以自己扩充系统功能。

要求:

1、在处理每个题目时,要求从分析题目的需求入手,按设计抽象数据类型、构思算法、通过设计实现抽象数据类型、编制上机程序和上机调试等若干步骤完成题目,最终写出完整的分析报告。

前期准备工作完备与否直接影响到后序上机调试工作的效率。

在程序设计阶段应尽量利用已有的标准函数,加大代码的重用率。

2、设计的题目要求达到一定工作量(300行以上代码),并具有一定的深度和难度。

3、程序设计语言推荐使用C/C++,程序书写规范,源程序需加必要的注释;

4、每位同学需提交可独立运行的程序;

5、每位同学需独立提交设计报告书(每人一份),要求编排格式统一、规范、内容充实,不少于10页(代码不算);

6、课程设计实践作为培养学生动手能力的一种手段,单独考核

3.课程设计说明书

一需求分析

要求用到数据结构课上学到的线性表的知识,所以就要充分而清晰的理解关于线性表的知识。

要求实现的基本功能很简单,只有删除和插入,增加功能也不过是加上修改。

这些在数据结构课上已经讲过,只要能够理解关于线性表的几个相关的基本算法就可以了。

问题是将输入的信息保存入文件和从文件输出。

这里基本是自学的内容,而且要考虑到是否要自行选择保存的磁盘。

综上,做这个课题,要具备的知识就是线性表的基本算法,文件的保存和读取算法,必要的C或者C++知识(本次我将使用C实现),以及丰富的程序调适经验。

二概要设计

程序流程图

图1

三详细设计

1、哈夫曼树结点结构定义

structhfmnode

{

charnValue;//节点值

intweight;//权值

intpnIndex;//父结点下标

intlchildIndex,rchildIndex;//左右孩子的结点下标

};

哈夫曼树类定义

classhuffmanTree{

public:

voidcode(charnvalue[],intw[],intn);//对叶子结点编码

voiddecode(charnvalue[],charhfmcode[],intn);//对叶子结点译码

voidOutput(huffmanTreeht,intn);//输出哈夫曼树

//private:

hfmnodehfmNode[2000];//用数组存储哈夫曼结点

voidcreatHfmTree(charnvalue[],intw[],intn);//创建哈夫曼树

voidselect(intpos,int&nodeOne,int&nodeTwo);//查询最小的两个结点

};

2、主要函数及相关功能

1在数组hfmNode中从O开始到pos位置,查找哈夫曼树外的权值最小的两个结点的位置

voidhuffmanTree:

:

select(intpos,int&nodeOne,int&nodeTwo)

2创建哈夫曼树,nvalue是结点值,w是权值,n是叶子结点的个数

voidhuffmanTree:

:

creatHfmTree(charnvalue[],intw[],intn)

3求哈夫曼树的编码nvalue是结点值数组,w是权值数组n是叶子结点的个数

voidhuffmanTree:

:

code(charnvalue[],intw[],intn)

4哈夫曼译码nvalue为结点值数组hfmcode为哈夫曼编码,n个叶子结点

voidhuffmanTree:

:

decode(charnvalue[],charhfmcode[],intn)

5检查输入的字符值是否合法

boolisChar(conststring&str)

6输出哈夫曼树,字符,权值,以及它对应的编码

voidhuffmanTree:

:

Output(huffmanTreeht,intn)

 

3、源程序

#include

usingnamespacestd;

structhfmnode//哈夫曼树结点结构定义

{

charnValue;//节点值

intweight;//权值

intpnIndex;//父结点下标

intlchildIndex,rchildIndex;//左右孩子的结点下标

};

classhuffmanTree//哈夫曼树类定义

{

public:

voidcode(charnvalue[],intw[],intn);//对叶子结点编码

voiddecode(charnvalue[],charhfmcode[],intn);//对叶子结点译码

voidOutput(huffmanTreeht,intn);//输出哈夫曼树

//private:

hfmnodehfmNode[2000];//用数组存储哈夫曼结点

voidcreatHfmTree(charnvalue[],intw[],intn);//创建哈夫曼树

voidselect(intpos,int&nodeOne,int&nodeTwo);//查询最小的两个结点

};

//在数组hfmNode中从O开始到pos位置,查找哈夫曼树外的权值最小的两个结点的位置

voidhuffmanTree:

:

select(intpos,int&nodeOne,int&nodeTwo)

{

longw1,w2;

w1=w2=88888;

for(inti=0;i<=pos;i++)

{

if(hfmNode[i].pnIndex==0)

if(hfmNode[i].weight

{

w1=hfmNode[i].weight;

nodeOne=i;

}

}

for(intj=0;j<=pos;j++)

{

if(hfmNode[j].pnIndex==0)

if(hfmNode[j].weight

=j)

{

w2=hfmNode[j].weight;

nodeTwo=j;

}

}

}

//创建哈夫曼树,nvalue是结点值,w是权值,n是叶子结点的个数

voidhuffmanTree:

:

creatHfmTree(charnvalue[],intw[],intn)

{

intpos;

for(pos=1;pos<=n;pos++)

{

hfmNode[pos].nValue=nvalue[pos-1];//结点值

hfmNode[pos].weight=w[pos-1];//权值

hfmNode[pos].pnIndex=hfmNode[pos].lchildIndex=hfmNode[pos].rchildIndex=0;

}

//设置数组hfmNode中的其他结点

for(pos=n+1;pos<=2*n-1;pos++)

{

intnodeOne,nodeTwo;

select(pos-1,nodeOne,nodeTwo);

hfmNode[nodeOne].pnIndex=hfmNode[nodeTwo].pnIndex=pos;//把hfmNode[nodeOne]和hfmNode[nodeTwo]两个结点加入哈夫曼树,设置他们的父结点位置为pos

hfmNode[pos].lchildIndex=nodeOne;//设置pos结点的左孩子为nodeOne

hfmNode[pos].rchildIndex=nodeTwo;//设置pos结点的右孩子为nodeTwo

hfmNode[pos].weight=hfmNode[nodeOne].weight+hfmNode[nodeTwo].weight;//设置pos结点的权值为左右孩子权值的和

hfmNode[pos].pnIndex=0;//pos父结点为0

}

}

//求哈夫曼树的编码nvalue是结点值数组,w是权值数组n是叶子结点的个数

voidhuffmanTree:

:

code(charnvalue[],intw[],intn)

{

creatHfmTree(nvalue,w,n);

inti,j,c,f;

intstart;

char*cd;

cd=newchar[n];//用于存储哈夫曼编码的动态空间

cd[n-1]='\0';//编码结束符

cout<<"结点值编码"<

for(i=1;i<=n;i++)//逐个字符求哈夫曼编码

{

start=n-1;//编码结束符位置

for(c=i,f=hfmNode[i].pnIndex;f!

=0;c=f,f=hfmNode[f].pnIndex)//从叶子到根逆向求编码

{

if(hfmNode[f].lchildIndex==c)

cd[--start]='0';

else

cd[--start]='1';

}

cout<<""<

for(j=start;j

cout<

cout<

}

delete[]cd;//释放空间

}

///哈夫曼译码nvalue为结点值数组hfmcode为哈夫曼编码,n个叶子结点

voidhuffmanTree:

:

decode(charnvalue[],charhfmcode[],intn)

{

inti,f;

charc;

for(i=0;i

{

//左0右1

for(f=2*n-1;hfmNode[f].lchildIndex!

=0&&hfmNode[f].rchildIndex!

=0;)

{

c=hfmcode[i];

if(c=='1')

{

f=hfmNode[f].rchildIndex;

i++;

}

else

{

f=hfmNode[f].lchildIndex;

i++;

}

}

cout<

}

cout<

}

////////检查输入的字符值是否合法

boolisChar(conststring&str)

{

inti;

for(i=0;i!

=str.length();i++)

{

if(!

isdigit(str[i]))

{

continue;

}

else

returnfalse;

}

returntrue;

}

/////////////////////////////////OUTPUT***********OUTPUToutput*****************

voidhuffmanTree:

:

Output(huffmanTreeht,intn)

//输出哈夫曼树,

{

cout<<"哈夫曼树储存结构模拟:

"<

cout<<"hfmNodeweightpnIndexlchildIndexrchildIndex"<

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

//cout<

printf("%4d%12d%10d%14d%16d\n",i,hfmNode[i].weight,hfmNode[i].pnIndex,hfmNode[i].lchildIndex,hfmNode[i].rchildIndex);

}

//*************---Main---*************//

//**************---======************//

voidmain()

{

//inti=1;

//while(i=1)

{

cout<<""<

cout<<"*****************--构造哈夫曼树--******************"<

intn=5;//字符和权值个数

cout<<"请输入字符集大小n:

"<

cin>>n;

charstr['n'];

//str[n-1]='\0';

charg;

charstr2[2000];//存储哈夫曼编码

intw[26];

huffmanTreeobj;

cout<<"请输入"<

"<

cin>>str;

//输入字符不合法

while(isChar(str)==0||strlen(str)!

=n)

{

cout<

cout<<"输入错误,请重新输入"<

cin>>str;

}

////////////////////////////////////////////

//Output();

//////////////////////////////////////////////

//intn=strlen(str);

cout<

gocd:

cout<<"输入对应权值:

"<

for(inti=0;i

cin>>w[i];

cout<

intm;

while

(1)

{

cout<<"请选择输入0或1:

"<

cout<<"***0、模拟输出哈夫曼树***"<

cout<<"***1、进行编码***********"<

cout<<"***2、进行译码***********"<

cin>>m;

switch(m)

{

case0:

{

obj.creatHfmTree(str,w,n);

obj.Output(obj,n);///////////////////////////////////////////OUTput

cout<

}break;

case1:

{

cout<<"各节点编码如下:

"<

obj.code(str,w,n);

cout<

}break;

case2:

break;

default:

cout<<"很抱歉,输入错误!

请重新输入:

"<

}

if(m==2)

break;

}

godc:

cout<

"<

cin>>str2;

cout<

cout<<"译码结果如下:

"<

obj.decode(str,str2,n);

cout<

cout<

cout<<"是否继续译码(Y/N)?

"<

getchar();

g=getchar();

if(g=='Y')

gotogodc;//继续译码

cout<<"是否继续编码(Y/N)?

"<

getchar();

g=getchar();

if(g=='Y')

gotogocd;//继续编码

}

}

四设计与调试分析

从上面的程序可以看出,有些地方时没有办法限制的,比如说输入整型变量的时候,没有办法限制其不能输入字符型。

在调试的过程中所遇到的问题很多。

 

五用户手册

1本程序可以在vc++5.0和vc++6.0的环境下运行。

2在vc中创建一个工程,将源程序复制到.cpp中,编译链接就可以。

3选择编译、运行以后会出现运行界面,选择相应的选项,根据提示即可进行演示。

界面如下:

4、请如数字符集大小n,就是要求用户输入哈夫曼树叶子结点的个数

 

六测试成果

 

测试结束

八.课程设计心得

我相信经过短短几天除了吃饭,睡觉,上课就天天坐在电脑面前编程,那编程水平没有提高是绝对不可能的,让你每天24小时有18个小时是坐在电脑面前编程,我相信,你一定会成为一出类拔萃的程序员。

设计心得,时间太短,忙不过来,同时要设计的东西太多,这个和知识学的不精也有关系,如果给充分的时间,我相信没有什么解决不了的!

谢谢老师的指导!

 

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

当前位置:首页 > 高等教育 > 军事

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

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