数据结构课程设计电文编码译码哈夫曼编码Word文档下载推荐.docx

上传人:b****2 文档编号:14738464 上传时间:2022-10-24 格式:DOCX 页数:16 大小:253.10KB
下载 相关 举报
数据结构课程设计电文编码译码哈夫曼编码Word文档下载推荐.docx_第1页
第1页 / 共16页
数据结构课程设计电文编码译码哈夫曼编码Word文档下载推荐.docx_第2页
第2页 / 共16页
数据结构课程设计电文编码译码哈夫曼编码Word文档下载推荐.docx_第3页
第3页 / 共16页
数据结构课程设计电文编码译码哈夫曼编码Word文档下载推荐.docx_第4页
第4页 / 共16页
数据结构课程设计电文编码译码哈夫曼编码Word文档下载推荐.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

数据结构课程设计电文编码译码哈夫曼编码Word文档下载推荐.docx

《数据结构课程设计电文编码译码哈夫曼编码Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计电文编码译码哈夫曼编码Word文档下载推荐.docx(16页珍藏版)》请在冰豆网上搜索。

数据结构课程设计电文编码译码哈夫曼编码Word文档下载推荐.docx

二、设计要求

对输入的一串电文字符实现哈夫曼编码,再对哈夫曼编码生成的代码串进行译码,输出电文字符串。

通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。

电报通信是传递文字的二进制码形式的字符串。

但在信息传递时,总希望总长度能尽可能短,即采用最短码。

假设每种字符在电文中出现的次数为Wi,编码长度为Li,电文中有n种字符,则电文编码总长度为∑WiLi。

若将此对应到二叉树上,Wi为叶结点的权,Li为根结点到叶结点的路径长度。

那么,∑WiLi恰好为二叉树上带权路径长度。

因此,设计电文总长最短的二进制前缀编码,就是以n种字符出现的频率作权,构造一棵哈夫曼树,此构造过程称为哈夫曼编码。

设计实现的功能:

(1)哈夫曼树的建立;

(2)哈夫曼编码的生成;

(3)编码文件的译码。

三、概要设计

哈夫曼编\译码器的主要功能是先建立哈夫曼树,然后利用建好的哈夫曼树生成哈夫曼编码后进行译码。

在数据通信中,经常需要将传送的文字转换成由二进制字符0、1组成的二进制串,称之为编码。

构造一棵哈夫曼树,规定哈夫曼树中的左分之代表0,右分支代表1,则从根节点到每个叶子节点所经过的路径分支组成的0和1的序列便为该节点对应字符的编码,称之为哈夫曼编码。

最简单的二进制编码方式是等长编码。

若采用不等长编码,让出现频率高的字符具有较短的编码,让出现频率低的字符具有较长的编码,这样可能缩短传送电文的总长度。

哈夫曼树课用于构造使电文的编码总长最短的编码方案。

设计包含的几个方面:

①哈夫曼树的建立

赫夫曼树的建立由赫夫曼算法的定义可知,初始森林中共有n棵只含有根结点的二叉树。

算法的第二步是:

将当前森林中的两棵根结点权值最小的二叉树,合并成一棵新的二叉树;

每合并一次,森林中就减少一棵树,产生一个新结点。

显然要进行n-1次合并,所以共产生n-1个新结点,它们都是具有两个孩子的分支结点。

由此可知,最终求得的哈夫曼树中一共有2n-1个结点,其中n个结点是初始森林的n个孤立结点。

并且哈夫曼树中没有度数为1的分支结点。

我们可以利用一个大小为2n--1的一维数组来存储赫夫曼树中的结点。

定义的结构体类型如下:

typedefstruct

{

chardata;

//结点字符

intweight;

//权值

intparent;

//双亲结点

intlchild;

//左孩子结点

intrchild;

//右孩子结点

}HTNode;

②哈夫曼编码

要求电文的哈夫曼编码,必须先定义哈夫曼编码类型,根据设计要求和实际需要定义的类型如下:

typedetstruct{

charcd[N];

//存放编码的数组

intstart;

//从start开始读cd中的哈夫曼编码

}Hcode;

//编码结构体类型

③代码文件的译码

译码的基本思想是:

读文件中编码,并与原先生成的哈夫曼编码表比较,遇到相等时,即取出其对应的字符存入一个新串中。

四、详细设计

①字符统计

intjsq(char*s,intcnt[],charstr[])

{char*p;

inti,j,k;

for(i=1;

i<

=256;

i++)

cnt[i]=0;

for(p=s;

*p!

='

\0'

;

p++)

k=*p;

cnt[k]++;

}

j=0;

for(i=1,j=0;

if(cnt[i]!

=0)

{

j++;

}

returnj;

②哈夫曼树的算法

voidCreateHT(HTNodeht[],intn,charstr[],intcn[])//创建哈夫曼树函数

{for(intinput=1;

input<

input++)

str[input]=input;

intl=0;

for(intoutput=1;

output<

output++)

if(cn[output]!

{ht[l].data=str[output];

//按字母顺序将出现的字母依次存入数组ht[]

ht[l].weight=cn[output];

l++;

inti,k,lnode,rnode;

intmin1,min2;

for(i=0;

2*n-1;

i++)

ht[i].parent=ht[i].lchild=ht[i].rchild=0;

//所有结点的相关域置初值0

for(i=n;

i++)//构造哈夫曼树

min1=min2=MAX;

//int的范围是-32768-32767

lnode=rnode=0;

//lnode和rnode记录最小权值的两个结点位置

for(k=0;

k<

=i-1;

k++)//选出每次外层循环最小权值的两个结点

if(ht[k].parent==0)//只在尚未构造二叉树的结点中查找

{

if(ht[k].weight<

min1)//比min1小时

{

min2=min1;

rnode=lnode;

min1=ht[k].weight;

lnode=k;

}

elseif(ht[k].weight<

min2)//比min1大,比min2小

min2=ht[k].weight;

rnode=k;

}

}

ht[lnode].parent=i;

ht[rnode].parent=i;

//两个最小节点的父节点是i

ht[i].weight=ht[lnode].weight+ht[rnode].weight;

//两个最小节点的父节点权值为两个最小节点权值之和

ht[i].lchild=lnode;

ht[i].rchild=rnode;

//父节点的左节点和右节点

③哈夫曼编码

voidCreateHCode(HTNodeht[],HCodehcd[],intn)

inti,p,c;

HCodehc;

n;

i++)//根据哈夫曼树求哈夫曼编码

hc.start=n;

//初始位置

c=i;

//从叶子结点ht[i]开始上溯

p=ht[i].parent;

while(p!

=0)//循序直到树根结点结束循环

hc.cd[hc.start--]=(ht[p].lchild)==c?

'

0'

:

1'

//左孩子记为0,右孩子记为1

c=p;

p=ht[p].parent;

//与上句c=i;

p=ht[i].parent同义,促进循环

hc.start++;

//start指向哈夫曼编码hc.cd[]中最开始字符

hcd[i]=hc;

④哈夫曼译码

voiddeHCode(HTNodeht[],HCodehcd[],intn,charstr[])//译码函数

printf("

输出译码结果为:

\n"

);

inti,j,k,x,m=0;

charcode[MAX];

MAX;

for(j=0;

j<

j++)

if(str[i]==ht[j].data)//循环查找与输入字符相同的编号,相同的就输出这个字符的编码

{

for(k=hcd[j].start;

=n;

k++)

code[m]=hcd[j].cd[k];

//将输出的编码赋值到数组中

m++;

break;

//输出完成后跳出当前for循环

code[m]='

#'

//把要进行译码的字符串存入code数组中

while(code[0]!

m=0;

//m为想同编码个数的计数器

for(k=hcd[i].start,j=0;

k++,j++)//j为记录所存储这个字符的编码个数

{

if(code[j]==hcd[i].cd[k])//当有相同编码时m值加1

m++;

if(m==j)//当输入的字符串与所存储的编码字符串个数相等时则输出这个的data数据

printf("

%c"

ht[i].data);

for(x=0;

code[x-j]!

x++)//把已经使用过的code数组里的字符串删除

code[x]=code[x+j];

//删除j个数,往前移动j位

⑤主函数

voidmain()

charst[MAX],sst[MAX];

intcn[257];

intn,i;

printf("

请输入字符串(任意字符):

gets(st);

n=jsq(st,cn,sst);

///////////////////////////99

for(i=0;

99;

sst[i]=st[i];

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

HTNodeht[M];

HCodehcd[N];

CreateHT(ht,n,st,cn);

CreateHCode(ht,hcd,n);

outputHCode(ht,hcd,n);

editHCode(ht,hcd,n,sst);

deHCode(ht,hcd,n,sst);

五、调试

输出哈夫曼编码

输出编码结果

输出译码结果

附录

源程序

#include<

stdio.h>

string.h>

//gets()函数需要

#defineN256//义用N表示50叶节点数

#defineM2*N-1//用M表示节点总数当叶节点数位n时总节点数为2n-1

#defineMAX32767

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

当前位置:首页 > 高等教育 > 研究生入学考试

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

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