信息论霍夫曼编码译码实验报告.docx

上传人:b****8 文档编号:29909290 上传时间:2023-08-03 格式:DOCX 页数:7 大小:16.08KB
下载 相关 举报
信息论霍夫曼编码译码实验报告.docx_第1页
第1页 / 共7页
信息论霍夫曼编码译码实验报告.docx_第2页
第2页 / 共7页
信息论霍夫曼编码译码实验报告.docx_第3页
第3页 / 共7页
信息论霍夫曼编码译码实验报告.docx_第4页
第4页 / 共7页
信息论霍夫曼编码译码实验报告.docx_第5页
第5页 / 共7页
点击查看更多>>
下载资源
资源描述

信息论霍夫曼编码译码实验报告.docx

《信息论霍夫曼编码译码实验报告.docx》由会员分享,可在线阅读,更多相关《信息论霍夫曼编码译码实验报告.docx(7页珍藏版)》请在冰豆网上搜索。

信息论霍夫曼编码译码实验报告.docx

信息论霍夫曼编码译码实验报告

实验一

一、实验背景

*哈夫曼编码(HuffmanCoding)是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。

Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般叫作Huffman编码。

二、实验要求

*利用程序实现哈夫曼编码,以加深对哈夫曼编码的理解,并锻炼编程能力。

三、代码分析

#include

#definen3//叶子数目

#definem(2*n-1)//结点总数

#definemaxval10000.0//maxval是float类型的最大值

#definemaxsize100//哈夫曼编码的最大位数

typedefstruct//定义霍夫曼树结构体

{

charch;//消息

floatweight;//所占权重

intlchild,rchild,parent;//定义左孩子、右孩子

}hufmtree;

typedefstruct//定义霍夫曼编码结构体

{

charbits[n];//位串

intstart;//编码在位串中的起始位置

charch;//字符

}codetype;

voidhuffman(hufmtreetree[]);//建立哈夫曼树

voidhuffmancode(codetypecode[],hufmtreetree[]);//根据哈夫曼树求出哈夫曼编码

voiddecode(hufmtreetree[]);//依次读入电文,根据哈夫曼树译码

voidmain()

{

printf("——哈夫曼编码——\n");

printf("信源共有%d个符号\n",n);

hufmtreetree[m];//m个结点,即有m个树形结构

codetypecode[n];//信源有n个消息,则需要n个编码

inti,j;//循环变量

huffman(tree);//建立哈夫曼树

huffmancode(code,tree);//根据哈夫曼树求出哈夫曼编码

printf("【输出每个字符的哈夫曼编码】\n");

for(i=0;i

{

printf("%c:

",code[i].ch);

for(j=code[i].start;j

printf("%c",code[i].bits[j]);

//“消息:

该消息的编码”

printf("\n");

}

printf("【读入电文,并进行译码】\n");

decode(tree);//依次读入电文,根据哈夫曼树译码

}

voidhuffman(hufmtreetree[])//建立哈夫曼树

{

inti,j,p1,p2;//p1,p2分别记住每次合并时权值最小和次小的两个根结点的下标

floatsmall1,small2,f;

charc;

for(i=0;i

{

tree[i].parent=0;

tree[i].lchild=-1;

tree[i].rchild=-1;

tree[i].weight=0.0;

}

printf("【依次读入前%d个结点的字符及权值(中间用空格隔开)】\n",n);

for(i=0;i

{

printf("输入第%d个字符为和权值",i+1);

scanf("%c%f",&c,&f);

getchar();//吸收回车符

tree[i].ch=c;

tree[i].weight=f;//将接收到的结点的字符及权值存入它对应的结构体数据中

}

for(i=n;i

{

p1=0;p2=0;

small1=maxval;small2=maxval;//maxval是float类型的最大值

for(j=0;j

{

if(tree[j].parent==0)//还未找到父结点的

if(tree[j].weight

{

small2=small1;//改变最小权、次小权及对应的位置

small1=tree[j].weight;

p2=p1;

p1=j;

}

elseif(tree[j].weight

{

small2=tree[j].weight;//改变次小权及位置

p2=j;

}

}

//找出的两个结点是新节点i的两个孩子

tree[p1].parent=i;

tree[p2].parent=i;

tree[i].lchild=p1;//最小权根结点是新结点的左孩子

tree[i].rchild=p2;//次小权根结点是新结点的右孩子

tree[i].weight=tree[p1].weight+tree[p2].weight;

}

}//huffman

//codetypecode[]为求出的哈夫曼编码

//hufmtreetree[]为已知的哈夫曼树

voidhuffmancode(codetypecode[],hufmtreetree[])//根据哈夫曼树求出哈夫曼编码

{

inti,c,p;

codetypecd;//缓冲变量

for(i=0;i

{

cd.start=n;//编码在位串中的起始位置

cd.ch=tree[i].ch;

c=i;//从叶结点出发向上回溯,第i个叶结点

p=tree[i].parent;//tree[p]是tree[i]的父结点

while(p!

=0)

{

cd.start--;

if(tree[p].lchild==c)

cd.bits[cd.start]='0';//tree[i]是左子树,生成代码'0'else

cd.bits[cd.start]='1';//tree[i]是右子树,生成代码'1'c=p;//c记录此时的父结点

p=tree[p].parent;//p记录新的父结点,即原来的父结点的父结点,向上溯回

}

code[i]=cd;//第i+1个字符的编码存入code[i]}

}//huffmancode

voiddecode(hufmtreetree[])//依次读入电文,根据哈夫曼树译码{

inti,j=0;

charb[maxsize];

i=m-1;//从根结点开始往下搜索

printf("输入发送的编码:

");

gets(b);

printf("译码后的字符为");

while(b[j]!

='\0')

{

if(b[j]=='0')

i=tree[i].lchild;//走向左子树

else

i=tree[i].rchild;//走向右子树

if(tree[i].lchild==-1)//如果回到叶结点,则把该结点的消息符号输出

{

printf("%c",tree[i].ch);

i=m-1;//回到根结点

}

j++;

}

printf("\n");

if(tree[i].lchild!

=-1&&b[j]=='\0')//电文读完,但尚未到叶子结点printf("\nERROR\n");//输入电文有错

}//decode

四、实验补充说明

解码时,以回车键结束输入电文。

已修复“电文读完,但尚未到叶子结点”这种情况下不能显示”ERROR”的错误。

构建父结点时,使用的序号i是在[n,m-1]的,最初的消息在结点的序号在[0,n-1],每次寻找新的父结点,都是从0到i寻找,所以就是会优先叶子结点进行合并,所以这是一种方差最小的最优霍夫曼编码。

 

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

当前位置:首页 > 总结汇报 > 其它

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

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