数据结构课程设计Huffman编译码器Word下载.docx
- 文档编号:21144503
- 上传时间:2023-01-27
- 格式:DOCX
- 页数:40
- 大小:498.92KB
数据结构课程设计Huffman编译码器Word下载.docx
《数据结构课程设计Huffman编译码器Word下载.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计Huffman编译码器Word下载.docx(40页珍藏版)》请在冰豆网上搜索。
ADTHuffmanTree{
数据对象D:
D是具有相同特性的数据元素集合。
数据关系R:
若D为空,则R为空,称Huffmantree为空赫夫曼树。
若D不为空,则R={H},H是如下的二元关系:
在D中存在惟一的称为根的数据元素
它在关系H下无前驱;
若
则存在
,且
;
则
中存在惟一的元素
,且存在
上的关系
;
,则
,且存在
是一棵符合本定义的赫夫曼树,称为根的左子树,
是一棵符合本定义的赫夫曼树,称为根的右子树;
基本操作P:
InputHuffman(HuffmanHfm)
操作结果:
输入并存储字符和相应权值。
Select(HuffmanTreeHT,intend,int*s1,int*s2)
初始条件:
频率数组已经建立。
选择HT[1....i-1]中无双亲且权值最小的两个节点,其序号为s1,s2。
HuffmanCoding(HuffmanHfm)
w存放n个字符的权值(均>
0),构造赫夫曼树HT,并求出n个字符的构造赫夫曼编码HC。
InitHuffman(HuffmanHfm)
初始条件:
操作结果:
要求用户输入字符和相应权值,初始化赫夫曼数
Encoding(HuffmanHfm)
霍夫曼树HuffmanTree已经存在。
利用已建好的Huffman树(如不在内存,则从文件
hfmTree中读入),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。
Decoding(HuffmanHfm)
利用已建好的Huffman树将文件CodeFile中的代码进行译码,结果存入文件TextFile中。
Print(HuffmanHfm)
霍夫曼树HoffmanTree已经存在。
操作结果:
将文件CodeFile以紧凑格式显示在终端上,每行50个代码。
Treeprint(HuffmanHfm)
初始条件:
将已在内存中的哈夫曼树以凹入表的形式显示在终端上同时将此字符形式的哈夫曼树写入文件TreePrint中。
}ADTHuffmanTree;
2.存储结构定义
数据存储结构的C语言定义如下:
ypedefchar**HuffmanCode;
//动态分配数组存储哈夫曼表码表
typedefstruct{
unsignedintweight;
unsignedintparent,lchild,rchild;
}HTNode,*HuffmanTree;
//动态分配数组存储哈夫曼树
HuffmanTreeHT;
char*c;
intlength;
HuffmanCodeHC;
}Huffman;
HuffmanHfm;
//全局结构体变量,来存储字符与代码
3.基本操作
数据结构的基本操作实现如下:
/*输入函数,控制用户输入字符和相应权值*/
HuffmanInputHuffman(HuffmanHfm)
{
inti,n;
printf("
\n\n********************Initialization*********************\n"
);
Thecharsandweightswillbesavedinthefile:
\hfmTree\\n"
Pleaseinputthenumberofthechars:
"
scanf("
%d"
&
n);
if(n<
=1)
/*若只有一个数值则无需编码*/
OnlyOneChar!
ThereIsNoNeedForCoding!
"
printf("
\n"
scanf("
}
Hfm.HT=(HuffmanTree)malloc((2*n)*sizeof(HTNode));
Hfm.c=(char*)malloc((n+1)*sizeof(char));
for(i=1;
i<
=n;
i++)
{
printf("
Pleaseinputthechar:
scanf("
%s"
Hfm.c[i]);
Pleaseinputtheweightofthechar:
Hfm.HT[i].weight);
Hfm.HT[i].parent=0;
Hfm.HT[i].lchild=0;
Hfm.HT[i].rchild=0;
}
for(;
=2*n-1;
++i)
{
Hfm.HT[i].weight=0;
Hfm.HT[i].parent=0;
Hfm.HT[i].lchild=0;
Hfm.HT[i].rchild=0;
Hfm.length=n;
returnHfm;
/*选择HT[1....i-1]中无双亲且权值最小的两个节点,其序号为s1,s2*/
voidSelect(HuffmanTreeHT,intend,int*s1,int*s2)
inti;
intmin1=MAX_NUM;
intmin2;
for(i=1;
=end;
i++)//遍历查找权值最小的结点S1
if(HT[i].parent==0&
&
HT[i].weight<
min1)
{
*s1=i;
min1=HT[i].weight;
}
min2=MAX_NUM;
for(i=1;
i++)//遍历查找除S1外权值最小的结点S2
if(HT[i].parent==0&
(*s1!
=i)&
min2>
HT[i].weight)
*s2=i;
min2=HT[i].weight;
/**
*存放n个字符的权值(均〉0),构造哈夫曼树HT,
*并求出n个字符的构造哈夫曼编码HC
*/
HuffmanHuffmanCoding(HuffmanHfm)
inti,n,m,s1,s2,start;
intc,f;
char*cd;
n=Hfm.length;
if(n<
=1)returnHfm;
m=2*n-1;
for(i=n+1;
=m;
Select(Hfm.HT,i-1,&
s1,&
s2);
Hfm.HT[s1].parent=i;
//修改父亲位置
Hfm.HT[s2].parent=i;
Hfm.HT[i].lchild=s1;
//修改孩子位置
Hfm.HT[i].rchild=s2;
/*父亲结点权值为左右孩子权值之和*/
Hfm.HT[i].weight=Hfm.HT[s1].weight+Hfm.HT[s2].weight;
/*从叶子结点到根逆向求每个字符的哈夫曼编码*/
Hfm.HC=(HuffmanCode)malloc((n+1)*sizeof(char*));
cd=(char*)malloc(n*sizeof(char));
//分配求编码的工作空间
cd[n-1]='
\0'
//编码结束符
++i)//逐个字符求哈夫曼编码
start=n-1;
//编码结束符位置
/*从叶子到根逆向求编码*/
for(c=i,f=Hfm.HT[i].parent;
f!
=0;
c=f,f=Hfm.HT[f].parent)
if(c==Hfm.HT[f].lchild)
cd[--start]='
0'
else
1'
Hfm.HC[i]=(char*)malloc((n-start)*sizeof(char));
strcpy(Hfm.HC[i],&
cd[start]);
//从cd复制编码到Hfm.HC
free(cd);
//释放工作空间
returnHfm;
/*初始化哈夫曼数,要求用户输入字符和相应权值*/
HuffmanInitHuffman(HuffmanHfm)
intn,i;
charx;
FILE*fp;
fp=fopen("
hfmTree.txt"
"
r+"
//对文件hfmTree以读文本的形式打开
if(fp==NULL)
OpenhfmTree.txterror!
Hfm=InputHuffman(Hfm);
fp=fopen("
w+"
fprintf(fp,"
%d\n"
Hfm.length);
=Hfm.length;
fprintf(fp,"
%c%d"
Hfm.c[i],Hfm.HT[i].weight);
rewind(fp);
fclose(fp);
Hfm=HuffmanCoding(Hfm);
voidEncoding(HuffmanHfm)
inti=0,j=0,n;
charch[MAX];
FILE*fp,*fw;
\n\n*******************Encoding************************\n\n"
if((fw=fopen("
ToBeTran.txt"
))==NULL)
\nPleaseinputthesentence:
ch);
CodeFile.txt"
else
fscanf(fw,"
fclose(fw);
while(ch[j])
if(ch[j]==Hfm.c[i])
Hfm.HC[i]);
fprintf(fp,"
break;
}
j++;
rewind(fp);
fclose(fp);
voidDecoding(HuffmanHfm)
HuffmanTreep;
inti,n;
intj=0;
chard[500];
\n\n******************Decoding************************\n\n"
if((fp=fopen("
Pleaseinputthecode:
d);
else
fscanf(fp,"
//将文件中的字符输入到数组d中
}
\nThefileis:
TextFile.txt"
//以写入文件的形式打开TextFile
while(d[j])
p=&
Hfm.HT[2*n-1];
while(p->
lchild||p->
rchild)
if(d[j]=='
)
{i=p->
lchild;
p=&
Hfm.HT[i];
else
rchild;
j++;
%c"
Hfm.c[i]);
voidPrint(HuffmanHfm)
intm=1;
//计数器
charch;
FILE*fprint,fp;
\n\n************Outputthecodeofthechars************\n"
i++)//显示每一个字符对应的哈夫曼编码
Char:
%c\t"
Weight:
%d\t"
Hfm.HT[i].weight);
Code:
puts(Hfm.HC[i]);
fprint=fopen("
rb"
//fp=fopen("
CodePrint.txt"
while(feof(fprint)==0)
ch=fgetc(fprint);
//fprintf(fp,"
m++;
if(m%50==0)//保证每一行输出50个字符
\n\n"
fclose(fprint);
voidConvert_tree(unsignedcharT[100][100],ints,int*i,intj)
intk,m;
m=++(*i);
for(k=0;
k<
s;
k++)
T[m][k]='
'
T[m][k]=Hfm.HT[j].weight;
if(Hfm.HT[j].lchild)
Convert_tree(T,s+1,i,Hfm.HT[j].lchild);
if(Hfm.HT[j].rchild)
Convert_tree(T,s+1,i,Hfm.HT[j].rchild);
T[m][++k]='
voidTreeprinting(HuffmanHfm)
unsignedcharT[100][100];
intn=Hfm.length;
inti,j,m=0;
FILE*fp;
Convert_tree(T,0,&
m,2*n-1);
if((fp=fopen("
treeprint.txt"
wb+"
Openfiletreeprint.txterror!
\n以凹入表形式打印已建好的赫夫曼树:
for(j=0;
T[i][j]!
j++)
if(T[i][j]=='
)
{
printf("
fputc(T[i][j],fp);
T[i][j]);
fprintf(fp,"
\n此字符形式的哈夫曼树已写入文件treeprint.txt中.\n\n"
二、解题过程
1.问题分解
该问题主要应实现以下功能:
(1)I:
初始化(Initialization)。
从终端读入字符集大小n,以及n个字符和n个
权值,建立赫夫曼树,并将它存于文件hfmTree中。
(2)E:
编码(Encoding)。
利用已建好的赫夫曼树(如不在内存,则从文件hfmTree中读入),对文件ToBeTran中的正文进行编码,然后将结果存入文件
CodeFile中。
(3)D:
译码(Decoding)。
利用已建好的赫夫曼树将文件CodeFile中的代码进
行译码,结果存入文件Textfile中。
(4)P:
印代码文件(Print)。
将文件CodeFile以紧凑格式显示在终端上,每行
50个代码。
同时将此字符形式的编码文件写入文件CodePrin中。
(5)T:
印赫夫曼树(Treeprinting)。
将已在内存中的赫夫曼树以直观的方式(比如树)显示在终端上,同时将此字符形式的赫夫曼树写入文件TreePrint中。
2.模块结构
系统主要由6个模块组成,如图所示:
模块之间的结构如下:
3.解题思路
各模块的实现步骤为:
.主程序
main()
InitHuffman(HuffmanHfm);
Encoding(HuffmanHfm);
Decoding(HuffmanHfm);
Print(HuffmanHfm);
Treeprint(HuffmanHfm);
.其他模块:
{
FOR(i=1;
IF(HT[i].parent是最小的)
THENHT[i].parent——>
*s1
IF(HT[i].parent是次最小的)
*s2
FOR(i=n+1;
++i)
修改父亲位置;
修改孩子位置;
父亲结点权值为左右孩子权值之和;
/*从叶子结点到根逆向求每个字符的赫夫曼编码*/
FOR(i=1;
++i)//逐个字符求赫夫曼编码
{
start=n-1;
//编码结束符位置
for(c=i,f=Hfm.HT[i].parent;
c=f,f=Hfm.HT[f].parent)
IF(c==Hfm.HT[f].lchild)
cd[--start]='
ELSE
再从cd复制编码到Hfm.HC
RETURNHfm;
HuffmanInitHuffman(HuffmanHfm)
对文件hfmTree以读文本的形式打开
IF(fp==NULL)
调用InputHuffman函数,用户输入字符和相应权值存入赫夫曼数中
ELSE
输出"
TheHuffmantreehasalreadyexisted!
\nPleasechooseagain!
读入hfmTree中文本
作为独立结点对结点的parent,lchild,rchild分别赋值0
FOR(;
作为独立结点对结点的weight,parent,lchild,rchild分别赋值0
Hfm=HuffmanCoding(Hfm);
voidEncoding(HuffmanHfm)
\n\n*
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程设计 Huffman 译码器