1、5哈夫曼编码和译码的算法设计与实现1实验名称哈夫曼编码和译码的算法设计与实现实验方案实验成绩实验日期实 验 室信息系统设计与仿真室I实验操作实验台号班级姓名通信11-1BF 王琳实验结果 一、 实验目的1、掌握哈夫曼编码的二叉树结构表示方法;2、编程实现哈夫曼编码译码器;3、掌握贪心算法的设计策略。二、 实验任务 从文件中读取数据,构建哈夫曼树; 利用哈夫曼树,对输入明文进行哈夫曼编码; 利用哈夫曼树,对输入编码译码为明文。三、 实验设计方案1、 结构体设计Huffman树:包括字符,权,父亲下标,左孩子下标,右孩子下标#define N 29 /26个小写字母,逗号,句号和空格字符. str
2、uct treenode /静态链表 char c; /char int w; /weight int f; /father int l; /left child index int r; /right child index;struct treenode htree2*N-1; 2、 自定义函数设计1 函数原型声明void input(); /读取文件字符、权值数据void huffman(); /建立huffman树void getcode(int i, char *str); /得到单个字符的huffman编码void encode(char ch); /将明文进行huffman编码v
3、oid decode(char *str); /将huffman编码译为明文 读取文件字符、权值数据void input() int i; char c; int f; freopen(in.txt,r,stdin); for(i=0;iN;i+) c=getchar(); /接收字符 scanf(%d,&f); /接收权值 getchar(); /接收回车 hti.c=c; hti.w=f; hti.l=hti.f=hti.r=-1; /初始化父亲、左右孩子下标 freopen( CON, r, stdin); 建立huffman树/使用贪心法建立huffman树,每次选择权值最小的根结点v
4、oid huffman()void huffman() int j,k,n; input(); j=0; k=N; for(n=N;n2*N-1;n+) /建立huffman树,共合并N-1次 int r=0,s=0; htn.l=htn.f=htn.r=-1; while(rhtj.w) & jN) s+=htj.w; if(r=0) htn.l = j; /修改父亲、孩子下标 else htn.r=j; htj.f=n; j+; else s+=htk.w; if(r=0) htn.l = k; /修改父亲、孩子下标 else htn.r=k; htk.f=n; k+; r+; htn.w
5、=s; /修改权值 根据字符下标找到字符的huffman编码/根据字符所在的下标,从叶子结点往上搜索到根节点,然后逆置得到该字符的huffman编码void getcode(int i, char *str) int n,j,l=0; for(n=i;htn.f!=-1;n=htn.f) /沿着父亲往上搜索 int m=htn.f; if(n=htm.l) strl+=0; /左孩子记为0 else strl+=1; /右孩子记为1 for(j=0;j=(l-1)/2;j+) /将编码逆置 char t; t=strj; strj=strl-1-j; strl-1-j=t; strl=0; /
6、 str存放huffman编码,字符串结束标记 读入明文生成huffman编码void encode(char ch) int i; char strN; for(i=0;hti.c!=0;i+) if(hti.c=ch) /找字符下标 break; if (hti.c!=0) getcode(i,str); /得到字符的huffman编码 printf(%s,str); 将huffman编码串译码为明文void decode(char *str) while(*str!=0) int i; for(i=2*N-2;hti.l!=-1;) if(*str=0) i=hti.l; else i=
7、hti.r; str+; printf(%c,hti.c); 3、 主函数设计思路:主函数实现实验任务的基本流程。void main() char ch; int i; char str100; huffman(); /建立huffman树 printf(请输入明文:); /输入明文 while(ch=getchar()!=n) encode(ch); /得到huffman编码 printf(n); printf(n请按字符编码对应表输入密文:n); for(i=0;iN;i+) /显示字符编码对应表 printf(%c:,hti.c); encode(hti.c); printf(t); s
8、canf(%s,str); /输入编码串 decode(str); /翻译成明文 printf(n); 四、 测试1、字符权值数据存放在in.txt文件中:j 217z 309q 343x 505k 1183w 1328v 1531f 1899. 2058y 2815b 2918g 3061, 3069h 3724d 4186m 4241p 4283u 4910 5005c 6028s 6859l 6882n 7948o 8259t 8929r 9337i 9364a 10050e 119912、测试输入明文:you输出编码:111011*输入编码:010*输入解码:love五、 总结与讨论1
9、、问题与错误 对程序的思路不明确,算法也不是很懂。2、经验与收获 了解了新算法,有所接触3、改进与设想六、 源代码 #include #include #include #define N 29 struct treenode /静态链表 char c; /char int w; /weight int f; /father int l; /left child index int r; /right child index;struct treenode ht2*N-1;void input() int i; char c; int f; freopen(in.txt,r,stdin); f
10、or(i=0;iN;i+) c=getchar(); /接收字符 scanf(%d,&f); /接收权值 getchar(); /接收回车 hti.c=c; hti.w=f; hti.l=hti.f=hti.r=-1; /初始化父亲、左右孩子下标 freopen( CON, r, stdin); void huffman() int j,k,n; input(); j=0; k=N; for(n=N;n2*N-1;n+) int r=0,s=0; htn.l=htn.f=htn.r=-1; while(rhtj.w) & jN) s+=htj.w; if(r=0) htn.l = j; els
11、e htn.r=j; htj.f=n; j+; else s+=htk.w; if(r=0) htn.l = k; else htn.r=k; htk.f=n; k+; r+; htn.w=s; void getcode(int i, char *str) int n,j,l=0; for(n=i;htn.f!=-1;n=htn.f) int m=htn.f; if(n=htm.l) strl+=0; else strl+=1; for(j=0;j=(l-1)/2;j+) /inverse char t; t=strj; strj=strl-1-j; strl-1-j=t; strl=0; v
12、oid encode(char ch) int i; char strN; for(i=0;hti.c!=0;i+) if(hti.c=ch) /找到字符 break; if (hti.c!=0) getcode(i,str); printf(%s,str); void decode(char *str) while(*str!=0) int i; for(i=2*N-2;hti.l!=-1;) if(*str=0) i=hti.l; else i=hti.r; str+; printf(%c,hti.c); void main() char ch; int i; char str100; h
13、uffman(); printf(请输入明文:); while(ch=getchar()!=n) encode(ch); printf(n); printf(n请按字符编码对应表输入密文:n); for(i=0;iN;i+) printf(%c:,hti.c); encode(hti.c); printf(t); scanf(%s,str); decode(str); printf(n);实验名称哈夫曼编码和译码的算法设计与实现实验方案实验成绩实验日期实 验 室信息系统设计与仿真室I实验操作实验台号班级姓名通信11-1BF段思楠实验结果一、实验目的1、掌握哈夫曼编码的二叉树结构表示方法;2、编
14、程实现哈夫曼编码译码器;3、掌握贪心算法的设计策略。二、实验任务 从文件中读取数据,构建哈夫曼树; 利用哈夫曼树,对输入明文进行哈夫曼编码; 利用哈夫曼树,对输入编码译码为明文。三、实验设计方案1、 结构体设计Huffman树:包括字符,权,父亲下标,左孩子下标,右孩子下标#define N 29 /26个小写字母,逗号,句号和空格字符. struct treenode /静态链表 char c; /char int w; /weight int f; /father int l; /left child index int r; /right child index;struct treen
15、ode htree2*N-1; 2、 自定义函数设计2 函数原型声明void input(); /读取文件字符、权值数据void huffman(); /建立huffman树void getcode(int i, char *str); /得到单个字符的huffman编码void encode(char ch); /将明文进行huffman编码void decode(char *str); /将huffman编码译为明文 读取文件字符、权值数据void input() int i; char c; int f; freopen(in.txt,r,stdin); for(i=0;iN;i+) c
16、=getchar(); /接收字符 scanf(%d,&f); /接收权值 getchar(); /接收回车 hti.c=c; hti.w=f; hti.l=hti.f=hti.r=-1; /初始化父亲、左右孩子下标 freopen( CON, r, stdin); 建立huffman树/使用贪心法建立huffman树,每次选择权值最小的根结点void huffman()void huffman() int j,k,n; input(); j=0; k=N; for(n=N;n2*N-1;n+) /建立huffman树,共合并N-1次 int r=0,s=0; htn.l=htn.f=htn.
17、r=-1; while(rhtj.w) & jN) s+=htj.w; if(r=0) htn.l = j; /修改父亲、孩子下标 else htn.r=j; htj.f=n; j+; else s+=htk.w; if(r=0) htn.l = k; /修改父亲、孩子下标 else htn.r=k; htk.f=n; k+; r+; htn.w=s; /修改权值 根据字符下标找到字符的huffman编码/根据字符所在的下标,从叶子结点往上搜索到根节点,然后逆置得到该字符的huffman编码void getcode(int i, char *str) int n,j,l=0; for(n=i;
18、htn.f!=-1;n=htn.f) /沿着父亲往上搜索 int m=htn.f; if(n=htm.l) strl+=0; /左孩子记为0 else strl+=1; /右孩子记为1 for(j=0;j=(l-1)/2;j+) /将编码逆置 char t; t=strj; strj=strl-1-j; strl-1-j=t; strl=0; / str存放huffman编码,字符串结束标记 读入明文生成huffman编码void encode(char ch) int i; char strN; for(i=0;hti.c!=0;i+) if(hti.c=ch) /找字符下标 break;
19、if (hti.c!=0) getcode(i,str); /得到字符的huffman编码 printf(%s,str); 将huffman编码串译码为明文void decode(char *str) while(*str!=0) int i; for(i=2*N-2;hti.l!=-1;) if(*str=0) i=hti.l; else i=hti.r; str+; printf(%c,hti.c); 3、 主函数设计思路:主函数实现实验任务的基本流程。void main() char ch; int i; char str100; huffman(); /建立huffman树 print
20、f(请输入明文:); /输入明文 while(ch=getchar()!=n) encode(ch); /得到huffman编码 printf(n); printf(n请按字符编码对应表输入密文:n); for(i=0;iN;i+) /显示字符编码对应表 printf(%c:,hti.c); encode(hti.c); printf(t); scanf(%s,str); /输入编码串 decode(str); /翻译成明文 printf(n); 四、测试1、字符权值数据存放在in.txt文件中:j 217z 309q 343x 505k 1183w 1328v 1531f 1899. 205
21、8y 2815b 2918g 3061, 3069h 3724d 4186m 4241p 4283u 4910 5005c 6028s 6859l 6882n 7948o 8259t 8929r 9337i 9364a 10050e 119912、测试输入明文:you输出编码:111011*输入编码:010*输入解码:love五、总结与讨论1、问题与错误 对算法思路不是很清晰2、经验与收获3、改进与设想6、源代码 #include #include #include #define N 29 struct treenode /静态链表 char c; /char int w; /weight
22、int f; /father int l; /left child index int r; /right child index;struct treenode ht2*N-1;void input() int i; char c; int f; freopen(in.txt,r,stdin); for(i=0;iN;i+) c=getchar(); /接收字符 scanf(%d,&f); /接收权值 getchar(); /接收回车 hti.c=c; hti.w=f; hti.l=hti.f=hti.r=-1; /初始化父亲、左右孩子下标 freopen( CON, r, stdin);
23、void huffman() int j,k,n; input(); j=0; k=N; for(n=N;n2*N-1;n+) int r=0,s=0; htn.l=htn.f=htn.r=-1; while(rhtj.w) & jN) s+=htj.w; if(r=0) htn.l = j; else htn.r=j; htj.f=n; j+; else s+=htk.w; if(r=0) htn.l = k; else htn.r=k; htk.f=n; k+; r+; htn.w=s; void getcode(int i, char *str) int n,j,l=0; for(n=i
24、;htn.f!=-1;n=htn.f) int m=htn.f; if(n=htm.l) strl+=0; else strl+=1; for(j=0;j=(l-1)/2;j+) /inverse char t; t=strj; strj=strl-1-j; strl-1-j=t; strl=0; void encode(char ch) int i; char strN; for(i=0;hti.c!=0;i+) if(hti.c=ch) /找到字符 break; if (hti.c!=0) getcode(i,str); printf(%s,str); void decode(char *str) while(*st
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1