数据结构课程设计报告哈夫曼编码译码器Word格式.docx
- 文档编号:22514672
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:22
- 大小:229.47KB
数据结构课程设计报告哈夫曼编码译码器Word格式.docx
《数据结构课程设计报告哈夫曼编码译码器Word格式.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计报告哈夫曼编码译码器Word格式.docx(22页珍藏版)》请在冰豆网上搜索。
PC机
2)操作系统:
Windows2000/XP/2003
3)编译环境:
VisualC++6.0
4开发工具和编程语言
开发工具:
VISCALLc++6.0;
编程语言:
C语言。
5详细设计
#include<
stdio.h>
stdlib.h>
string.h>
typedefstruct//结点的结构
{
unsignedintweight;
//结点的权值
unsignedintparent,lchild,rchild;
}HTNode,*HuffmanTree;
//动态分配数组存储哈夫曼树
typedefchar**HuffmanCode;
//动态分配数组存储哈夫曼编码
HuffmanTreeHT;
HuffmanCodeHC;
intn=8;
constcharmenu[]=
"
|1建立哈夫曼树|\n"
|2查看哈夫曼编码|\n"
|3树形输出哈夫曼树|\n"
|4哈夫曼文件编码|\n"
|5哈夫曼文件解码|\n"
|6帮助|\n"
|7退出系统|\n"
;
constcharhelpsabout[]=
|主要功能:
|\n"
|利用哈夫曼编码进行通信可以大大提高信道的利用率,缩短信息的传输时间,降低|\n"
|传输成本。
但是,这要求在发送端通过一个编码系统对待传输的数据预先编码,在接收|\n"
|端将传来的数据进行译码(复原)。
对于双工信道,每端都要有一个完整的编/译码系|\n"
|统。
本系统即是为这样的信息收发站写一个哈夫曼码的编/译系统。
||\n"
voidHuffmantree();
voidHuffmancode();
voidpreorder();
voidstringcopy();
intmin();
voidselect();
voiddecode();
voidencode();
voidint_huffmantree();
voidprint_end();
voidprint_title();
voidprint_menu();
voidprint_helpabout();
voidprint_huffmancode();
voidprint_tree();
//------------------先序遍历----------------------------------------------------
voidpreorder(introot,intdepth)
{
inti;
for(i=1;
i<
=depth;
i++)
printf("
"
);
if(depth!
=0)
└"
else
printf("
%d"
HT[root].weight,depth);
if(root<
=n)
:
%s\n"
HC[root]);
//依次输出哈夫曼编码
\n"
if(HT[root].lchild!
{depth++;
preorder(HT[root].lchild,depth);
}
if(HT[root].rchild!
{preorder(HT[root].rchild,depth);
//--------------字符串拷贝函数----------------------------------------------------
voidstringcopy(char*strDest,char*strSrc)
char*strDestCopy=strDest;
if(!
(strDest&
&
strSrc))
ERROR!
"
while((*strDest++=*strSrc++)!
='
\0'
}
//--------返回哈夫曼树t的前i个结点中权值最小的树的根结点序号,函数select()调用------------
intmin(HuffmanTreet,inti)
intj,m;
unsignedintk=0xffffffff;
//k存最小权值,初值取为不小于可能的值
for(j=1;
j<
=i;
j++)//对于前i个结点
if(t[j].weight<
k&
t[j].parent==0)//t[j]的权值小于k,又是树的根结点
{k=t[j].weight;
//t[j]的权值赋给k
m=j;
//序号赋给m
t[m].parent=1;
//给选中的根结点的双亲赋非零值,避免第2次查找该结点
returnm;
//返回权值最小的根结点的序号
//----在哈夫曼树t的前i个结点中选择2个权值最小的树的根结点序号,s1为其中序号(权值)较小的----
voidselect(HuffmanTreet,inti,int&
s1,int&
s2)
intj;
s1=min(t,i);
//权值最小的根结点序号
s2=min(t,i);
//权值第2小的根结点序号
if(s1>
s2)//s1的序号大于s2的
{//交换
j=s1;
s1=s2;
//s1是权值最小的2个中序号较小的
s2=j;
//s2是权值最小的2个中序号较小的
//-------w存放n个字符的权值(均>
0),构造哈夫曼树HT----------------------------------------
voidHuffmantree(int*w)
intm,i,s1,s2;
HuffmanTreep;
if(n<
=1)//叶子结点数不大于n
return;
m=2*n-1;
//n个叶子结点的哈夫曼树共有m个结点
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
//0号单元未用
for(p=HT+1,i=1;
=n;
++i,++p,++w)//从1号单元开始到n号单元,给叶子结点赋值
{//p的初值指向1号单元
(*p).weight=*w;
//赋权值
(*p).parent=0;
//双亲域为空(是根结点)
(*p).lchild=0;
//左右孩子为空(是叶子结点,即单结点树)
(*p).rchild=0;
for(;
=m;
++i,++p)//i从n+1到m
//其余结点的双亲域初值为0
for(i=n+1;
++i)//建哈夫曼树
{//在HT[1~i-1]中选择parent为0且weight最小的两个结点,其序号分别为s1和s2
select(HT,i-1,s1,s2);
HT[s1].parent=HT[s2].parent=i;
//i号单元是s1和s2的双亲
HT[i].lchild=s1;
//i号单元的左右孩子分别是s1和s2
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
//i号单元的权值是s1和s2的权值之和
//-------并求出n个字符的哈夫曼编码HC--------------------------------------------------
voidHuffmancode()
intstart;
unsignedintf;
unsignedintc;
char*cd;
HC=(HuffmanCode)malloc((n+1)*sizeof(char*));
//分配n个字符编码的头指针
cd=(char*)malloc(n*sizeof(char));
//分配求编码的字符数组
cd[n-1]='
i++)//逐个字符求哈夫曼编码
start=n-1;
//编码结束符位置
for(c=i,f=HT[i].parent;
f!
=0;
c=f,f=HT[f].parent)//从叶子到根逆向求编码
if(HT[f].lchild==c)//c是其双亲的左孩子
cd[--start]='
0'
//由叶子向根赋值'
else//c是其双亲的右孩子
1'
HC[i]=(char*)malloc((n-start)*sizeof(char));
//为第i个字符编码分配空间
stringcopy(HC[i],&
cd[start]);
//从cd复制编码串到HC矩阵
free(cd);
//释放工作空间
//---------------------译码-----------------------------------------------------
voidencode()
{
FILE*fp1=NULL,*fp2=NULL;
charinput[20]="
input.txt"
output[20]="
output.txt"
请输入输入文件名(input.txt):
scanf("
%s"
input);
if((fp1=fopen(input,"
r"
))==NULL)
无此文件!
getchar();
return;
请输入输出文件名(output.txt):
output);
if((fp2=fopen(output,"
w"
不能创建文件!
inti,k;
unsignedint*w,p,m=0,j;
for(k=0;
!
feof(fp1);
k++)
if(fgetc(fp1)=='
'
)
m++;
}
哈夫曼编码为:
fp1=fopen(input,"
w=(unsignedint*)malloc(m*sizeof(unsignedint));
//动态生成存放m个权值的空间
for(j=0;
=m-1;
j++)
fscanf(fp1,"
w+j);
//依次输入原码
for(p=0;
p<
m;
p++)
for(i=0;
n;
if(*(w+p)==HT[i+1].weight)
{
fprintf(fp2,"
HC[i+1]);
}
fclose(fp1);
fclose(fp2);
\n输出完成.按任意键继续...."
getchar();
//-------------------------解码-------------------------------------------------
voiddecode()
charinput[20],output[20];
char*code;
code=(char*)malloc(n*sizeof(char));
inti,j;
哈夫曼译码为:
*(code+i)=fgetc(fp1);
*(code+i+1)='
for(j=0;
if(strcmp(code,HC[j+1])==0)
{
fprintf(fp2,"
%d"
HT[j+1].weight);
printf("
i=-1;
break;
//---------------------初始化哈夫曼树------------------------------------------
voidint_huffmantree()
system("
cls"
print_title();
int*w,i;
请输入权值的个数(>
1):
&
n);
w=(int*)malloc(n*sizeof(int));
//动态生成存放n个权值的空间
请依次输入%d个权值(整型):
n);
w+i);
Huffmantree(w);
//根据w所存的n个权值构造哈夫曼树HT,
Huffmancode();
//n个哈夫曼编码存于HC
print_end();
哈夫曼编码为:
%5d:
*(w+i-1),HC[i]);
按任意键返回..."
//-----------------哈夫曼编码菜单----------------------------------
voidprint_huffmancode()
system("
print_title();
HT[i].weight,HC[i]);
//--------------帮助菜单-------------------------------------------
voidprint_helpabout()
printf(helpsabout);
//----------------树形输出菜单--------------------------------------
voidprint_tree()
哈夫曼树为:
preorder(2*n-1,0);
print_end();
//--------------------选择菜单输出-------------------------------------------------
voidprint_menu()
while
(1)
intselected=0;
printf(menu);
>
请选择[1~7]"
scanf("
selected);
if(selected<
1||selected>
7)
printf("
错误的选择!
(请输入1~7).按任意键继续...."
getchar();
switch(selected){
case1:
int_huffmantree();
case2:
print_huffmancode();
case3:
print_tree();
case4:
encode();
case5:
decode();
case6:
print_helpabout();
case7:
exit(0);
voidprint_title()
+=============================================================================+\n"
|哈夫曼编码译码器|\n"
|DesignedByOrganne|\n"
voidprint_end()
voidmain()
intw[8]={5,29,7,8,14,23,3,11};
color17"
print_menu();
6调试分析
在调试过程中出现的一些问题:
1、输入语句中没有加取地址符号&
2、误把取地址运算符&
当作逻辑与&
3、误把赋值=当恒等==
4、条件语句(if)后误加分号
5、循环语句中改变了循环变量
6、作为输出结果的变量没有赋初值
7测试结果
8参考文献
1、严蔚敏《数据结构》(C语言版)清华大学出版社
2、徐晓凯编著《数据结构课程实验》,清华大学出版2002年第一版
3、张乃笑编著《数据结构与算法》电子工业出版社2004年10月
课程设计总结
通过这次课程设计,让我对一个程序的数据结构有更加全面更进一步的认识,根据不同的需求,采用不同的数据存储方式,不一定要用栈、二叉树等高级类型,又是用基本的一维数组,只要晕晕得当,也能达到相同的效果,甚至更佳,就如这次的课程设计,通过用for的多重循环,舍弃多余的循环,提高了程序的运行效率。
在编写这个程序的过程中,我们复习了之前学的基本语法,哈夫曼树最小路径的求取,哈夫曼编码以及译码的应用范围,程序结构算法等一系列的问题,它使我们对数据结构改变可看法。
在这次设计过程中,体会了学以致用,从中发现了学习的不足和薄弱环节,从而加以弥补。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程设计 报告 哈夫曼 编码 译码器