哈夫曼编码.docx
- 文档编号:11623819
- 上传时间:2023-03-29
- 格式:DOCX
- 页数:9
- 大小:29.81KB
哈夫曼编码.docx
《哈夫曼编码.docx》由会员分享,可在线阅读,更多相关《哈夫曼编码.docx(9页珍藏版)》请在冰豆网上搜索。
哈夫曼编码
约瑟夫环实验报告
1.需求分析
(1)初始化;从终端输入字符集的大小n,以及n个字符和n个权值建立哈夫曼树。
(2)输出哈夫曼树,及各字符对应的编码。
(3)编码:
利用建好的哈夫曼树,对输入的待发送电文进行编码。
同时输入原文及编码串。
(4)译码:
利用建好的哈夫曼树,对输入的已接收电文进行译码。
同时输入编码串及原文。
2.概要设计
1.统计字符频度
2.构造哈夫曼树
3.为每个叶子结点编码
4.编码
5.译码
3.详细设计
程序设计如下:
#include
#include
#include
#defineMAXLEAF100
structHTNode
{charletter;
intparent;
intlchild;
intrchild;
intweight;
};
structChNode
{
charletter;
intweight;
};
structHCode
{
charcode[MAXLEAF];
intm_start;
};//创建哈夫曼
voidCreateHT(HTNodeht[],intn,ChNodes[])
{
inti,k,s1,s2;
intm1,m2;
for(i=0;i<2*n-1;i++)
{
ht[i].parent=0;
ht[i].lchild=0;
ht[i].rchild=0;
ht[i].weight=0;
}
for(i=0;i { ht[i].letter=s[i].letter; ht[i].weight=s[i].weight; } printf("哈夫曼树初态为: \n"); printf("dataweightparentlchildrchild\n"); for(i=0;i<2*n-1;i++) { printf("%-6c%-6d? %-6d%-6d%-6d\n",ht[i].letter,ht[i].weight,ht[i].parent,ht[i].lchild,ht[i].rchild); } for(i=n;i<2*n-1;i++) { m1=m2=32767; s1=s2=0; for(k=0;k<=i-1;k++) { if(ht[k].parent==0) { if(ht[k].weight { m2=m1; s2=s1; m1=ht[k].weight; s1=k; } elseif(ht[k].weight { m2=ht[k].weight; s2=k; } } } ht[s1].parent=i; ht[s2].parent=i; ht[i].weight=ht[s1].weight+ht[s2].weight; ht[i].lchild=s1; ht[i].rchild=s2; } printf("\n哈夫曼树终态为: \n"); printf("dataweightparentlchildrchild\n"); for(i=0;i<2*n-1;i++) { printf("%-6c%-6d%-6d%-6d%-6d\n",ht[i].letter,ht[i].weight,ht[i].parent,ht[i].lchild,ht[i].rchild); } printf("\n"); }//哈夫曼编码 voidCreateCode(HTNodeht[],HCodehcd[],intn) { inti,f,letter; HCodehc; for(i=0;i { hc.m_start=n-1; letter=i; f=ht[i].parent; while(f! =-1) { if(ht[f].lchild==letter) hc.code[hc.m_start--]='0'; else hc.code[hc.m_start--]='1'; letter=f; f=ht[f].parent; } hc.m_start++; hcd[i]=hc; } printf("哈夫曼编码: \n"); printf("结点信息权值哈夫曼编码\n"); for(i=0;i { printf("%c%s%d%s",ht[i].letter,"",ht[i].weight,""); for(intj=hcd[i].m_start;j printf("%c",hcd[i].code[j]); printf("\n"); } }//译码 voidCoding(HTNodeht[],HCodehcd[],intn,charstr[]) { for(inti=0;str[i]! ='\0';i++) { for(intj=0;j { if(str[i]==ht[j].letter) { for(intk=hcd[j].m_start;k { printf("%c",hcd[j].code[k]); } break; } } } printf("\n"); } intmain() { charstr[MAXLEAF]; printf("**********************欢迎使用赫夫曼编译系统**********************\n"); printf("从键盘输入若干字符: \n"); scanf("%s",str); ChNodes[20]; memset(s,0,sizeof(ChNode)*20); intj=0; for(inti=0;str[i]! ='\0';i++) { intflag=0; for(intk=0;k { if(str[i]==s[k].letter) { s[k].weight++; flag=1; break; } } if(! flag) { s[j].letter=str[i]; s[j].weight=1; j++; } } HTNodeht[MAXLEAF]; memset(ht,0,sizeof(HTNode)*MAXLEAF); HCodehcd[MAXLEAF]; intnum=-1; while (1) { printf("************************主菜单********************************\n"); printf("**1.创建哈夫曼树并查看初态和终态**\n"); printf("**2.创建并查看哈夫曼编码**\n"); printf("**3.译码**\n"); printf("**4.退出**\n"); printf("****************************************************************\n"); scanf("%d",&num); if(num==0) break; switch(num) { case1: { CreateHT(ht,j,s); } break; case2: { CreateCode(ht,hcd,j); } break; case3: { charstr[MAXLEAF]; printf("请输入译文: \n"); scanf("%s",str); printf("译码后为: "); Coding(ht,hcd,j,str); } break; default: break; } printf("按任意键继续..."); getch(); system("cls"); } } 4.调试分析 在给每个字符编码时,由于编码是从根结点开始,所以选用与前序遍历相似的递归遍历形式。 其中需要一个字符型数组来记录路径和编码,由于递归一次才有一位编码,所以这个数组也要随着递归函数的进行而不断修改。 开始时我没有用指针最为参数而是直接将数组作为参数,结果发现每次调用递归函数时数组都是空。 原来我用的是值传递,数组就算修改了也无法返回。 这提醒了我之后运用递归函数时如果需要某个变量随函数递归而修改时应该使开始 菜单界面,选择 编码器 编码表 解码器 退出程序 关于程序 重新编码 输出程序信息 任意键操作 输入要编码的信息 输出编码 的结果 任意键操作 任意键操作 任意键操作 输出要编码的信息 输出编码表 输入要编码的信息 输出编码 的结果 输出 编码 输出翻译出的信息 任意键操作 结束 用地址传递而非值传递。 5.用户手册 1.该程序在windows系统下运行 2.先输入任意字符启动编译器,然后按照文字提示继续即可 6.测试结果 7.附录 #include #include #include #include #defineMAXLEAF100
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 哈夫曼 编码