1、哈夫曼编/译码系统的设计与实现2014 年 12 月 23 日学 号 姓 名 时 间专 业 计算机科学与技术 班 级实验题目:哈夫曼编/译码系统的设计与实现一、 实验目的(1) 了解哈夫曼树的特点及构造方法;(2) 了解最优哈夫曼树的特点;二、 实验分析:#include“stdio.h“#include“malloc.h“#include“string.h“#define char_num 8 typedef struct char ch ; int w; DFileNode ;/ 定义数据文件的元素类型void creatDataFile( )/创建数据文件FILE *f;char c;D
2、FileNode s;int i,a9; /数组 a 用来存放从 A-H 每个字符出现的次数;0 号单元不用for(i=1;is2)j=s1;s1=s2;s2=j;void print_huff_tree(HuffmanTree HT ,int n)/输出哈夫曼树,在必要时调用以验证算法的正确性HuffmanTree p;int i;printf(“字符 权 值 双 亲 左孩子 右孩子 指向编码的指针n“);for(p=HT+1,i=1;i%sn“,p-ch,p-weight,p-parent,p-lchild,p-rchild,p-next);void creatHuffmanTree( H
3、uffmanTree int m,i,s1,s2;HuffmanTree p;DFileNode s; /从文件中读数据时用;m=2*n-1;f1=fopen(“DataFile.dat“,“rb“);HT=(HuffmanTree)malloc(m+1)*sizeof(HTNode); /0 号单元未用for(p=HT+1,i=1;i=n;+i,+p)fread( /从文件中读一个数给 s,构造叶子(*p).ch=s.ch;(*p).weight=s.w;(*p).parent=0;(*p).lchild=0;(*p).rchild=0;(*p).next=NULL;fclose(f1);p
4、rintf(“n“);for(;i=m;+i,+p) (*p).ch= ;(*p).parent=0;(*p).lchild=0;(*p).rchild=0;(*p).next=NULL;for(i=n+1;i=m;+i)/建 n-1 个分支结点 / 在 HT1i-1中选择 parent 为 0 且 weight 最小的两个结点,其序号分别为s1 和 s2select(HT,i-1,s1,s2);HTs1.parent=HTs2.parent=i;HTi.lchild=s1;HTi.rchild=s2;HTi.weight=HTs1.weight+HTs2.weight;void Huffma
5、nCoding(HuffmanTree int i,start,c,f; cd=(char*)malloc(n*sizeof(char); / 分配求编码的工作空间cdn-1=0; / 编码结束符for(i=1;i=n;i+) / 逐个字符求赫夫曼编码start=n-1; / 编码结束符位置for(c=i,f=HTi.parent;f!=0;c=f,f=HTf.parent)/ 从叶子到根逆向求编码if(HTf.lchild=c)cd-start=0;elsecd-start=1;HTi.next=(char*)malloc(n-start)*sizeof(char);/ 为第 i 个字符编码
6、分配空间strcpy(HTi.next, / 从 cd 复制编码 (串)到 HCfree(cd); / 释放工作空间void EnCoding()/编码:对文件 ToBeTran.dat 中的文本进行编码,放在文件Code.txt 中FILE *f1, *f2; char s;int i;f2=fopen(“Code.txt“,“w“);/打开文件 Code.txt 为了写f1=fopen(“ToBeTran.dat“,“r“);/打开文件 ToBeTran.dat 为了读fgetc(f1);while(fread(while(HTi.ch!=s) i+;fputs(HTi.next,f2);
7、fclose(f1);fclose(f2);void Decoding( )/译码:对文件 CodeFile.dat 中的报文进行译码,放在文件Textfile.txt 中FILE *f1, *f2; char c;int s,p;f1=fopen(“CodeFile.dat“,“rb“);f2=fopen(“Textfile.txt“,“w“); p=2*char_num-1; /P 指向哈夫曼树的根while(fread(if(s=0) p=HTp.lchild; else p=HTp.rchild;if(HTp.lchild=0) c=HTp.ch; fputc(c,f2); p=2*c
8、har_num-1; /让 P 重新指向哈夫曼树的根fclose(f1);fclose(f2);void output_1( )/输出原文和对应的译文;FILE *f1, *f2; char c;int s;f1=fopen(“ToBeTran.dat“,“r“);/打开文件 ToBeTran.dat 为了读printf(“原文:“);while(fread(fclose(f1);f2=fopen(“Code.txt“,“r“);printf(“n 译文:“);while(fread(printf(“n“);fclose(f2);void output_2( )/输出报文和对应的原文;FILE
9、 *f1, *f2; char c;int s;f1=fopen(“CodeFile.dat“,“rb“);printf(“报文:“);while(fread(printf(“n“);fclose(f1);f2=fopen(“Textfile.txt“,“r“);printf(“原文:“);while(fread(printf(“n“);fclose(f2);void main()int i , j;creatDataFile( );/创建数据文件creatHuffmanTree(HT, char_num);/建哈夫曼树即初始化 Initialzationprintf(“初始的哈夫曼树:n“)
10、;print_huff_tree( HT, 2*char_num-1);/验证所建初始的哈夫曼树HuffmanCoding(HT, char_num);/编码printf(“编码后的哈夫曼树:n“);print_huff_tree( HT, 2*char_num-1);/验证编码后的哈夫曼树及编码for(i=1;i=8;i+) printf(“字符%c 的编码为:%-10s “ ,HTi.ch,HTi.next); if(i%3=0) printf(“n“);printf(“n“);creatToBeTran( );/创建原文文件 EnCoding();/编码output_1( );/输出creatCodeFile( );/创建报文文件 printf(“n“);Decoding();/译码output_2( );/输出三、实验输出结果:实验指导教师 杨育捷 实验成绩