信息论霍夫曼编码译码实验报告.docx
- 文档编号:29909290
- 上传时间:2023-08-03
- 格式:DOCX
- 页数:7
- 大小:16.08KB
信息论霍夫曼编码译码实验报告.docx
《信息论霍夫曼编码译码实验报告.docx》由会员分享,可在线阅读,更多相关《信息论霍夫曼编码译码实验报告.docx(7页珍藏版)》请在冰豆网上搜索。
信息论霍夫曼编码译码实验报告
实验一
一、实验背景
*哈夫曼编码(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寻找,所以就是会优先叶子结点进行合并,所以这是一种方差最小的最优霍夫曼编码。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 信息论 霍夫曼 编码 译码 实验 报告