1、完整版哈夫曼编码编译器课题:哈夫曼编码编译器设计一个哈夫曼编码/译码系统,对一个文本文件中的字符进行哈夫曼编码, 生成编码文件(压缩文件,后缀名.cod );反过来,可将一个压缩文件译码还原为一个文 本文件(.txt)。二、功能(1) 输入一个待压缩的英文文本文件,统计文本文件中各字符的个数作为 权值,生成哈夫曼树;(2) 将文本文件利用哈夫曼树进行编码,生成压缩文件(后缀名 cod)(3) 输入一个待解压的压缩文件名称,并利用相应的哈夫曼树将编码序列译 码。三、程序结构程序流程图执行程序选择(1)编码选择(0)退出选择(2)译码输入要译码文件名编码译码保存编码后的文件保存译码后的文件文字说明
2、Main 函数: Coding() 编码函数Tran sCode()译码函数Coding()编码函数:clearscree n()清屏函数Open()打开源码文件SearchStr()查找字符串中不同的字符及其出现的次数CreatHFMTree() 用每个字符出现的次数作为叶子节点的权值建立哈夫曼树HFMCode() 利用哈夫曼树对每个叶子节点进行编码,存入编码表中TotalCoding() 利用编码表对字符串进行最终编码Save()保存最终的哈夫曼编码TransCode(译码函数:clearscree n()清屏函数Open()打开编码文件DeCoding(); / 将编码进行解码存入字符串
3、数组中Save(); /保存译码后的字符串四、 算法说明1. 执行界面I微软拼音半:可供三个选择(1)编码(2)译码(3)退出执行(1)选择需要输入要编译的文件名需要输出编码保存文件名选择(1)执行完毕执行(2)选项输入要译码的编码文件名并输入保存的文件名选择(2)执行完毕执行(0)则退出该程序D :佈宦文件密未命名2. xM N M M-fMMKKWN M 哈夫曼 楫K N M M iNMKWK NMM MMMM 1编码。柏曲2.译码q HMMM 白逍MMWNMM MMMM MM十谱辅入相应操柞的序号(8-2)财MMMMMMMXMKMMMMMMMXXKMMHMMMXXXMKMProcess
4、exited! with return ualue 0 PrBB any kciij te continue , , r惯钦拼音半:五、报告总结该程序主要采用了哈夫曼编码译码方法,对 txt文件进行编译压缩,同时也能对编码后的文件进行解码,程序结构清晰,主干分两大部分:编码部分与解码部分, 各部分通过调用函数合理清晰的实现其功能。 程序中运用了一些文件的 C语言基本操作,例如打开文件open()、 保存文件save ()函数,但程序上对文件类型的处理还有一些缺点,不能实现文件类型的自 动保存,需要输入文件名字和类型。 通过这次课程设计, 不仅提高了自己的编程能力, 还让我知道自己在编程方面的缺
5、点,我以后会更加努力扩大自己的知识面提高自己的编程能力。#i nclude #in elude #in elude #define M 10000 /定义字符串最大长度#defi ne N 128 /定义叶子节点个数 typedef struct n ode /定义哈夫曼树节点结构体int weight;struct node *LChild,*RChild,*Pare nt; / 分别指向该节点的左孩子,右孩子,和双亲节点 struct node *next; /指向建立的哈夫曼树的下一个节点HFMNode,*HFMTree;typedef struct II定义哈夫曼编码的结构体char
6、ch; / 存储对应的字符char codeN+1; / 存储对应字符的编码 int start; / 存储编码的起始位置 CodeNode;int n; /存储真正叶子节点个数 void clearscreen() system(cls);void Open(char s) / 打开存放字符或编码的文件,将其存入字符串数组中 char name10;FILE *fp;int i=0;printf( 请输入要打开的文件名: ); gets(name); /要打开的文件名 if(fp=fopen(name,rt)=NULL)printf( 打开失败! n); / 若打开失败,则直接退出 exit
7、(1); si+=fgetc(fp); while(si-1!=EOF)si+=fgetc(fp);si=0; / 存取字符串结束 fclose(fp);void Save(char s) / 保存字符或编码到文件中 char name10;FILE *fp;printf( 请输入要保存的文件名: );gets(name); if(fp=fopen(name,wt)=NULL)printf( 存储失败! );exit(1);fputs(s,fp);printf(n 保存成功,文件名为 :%s。 n,name); printf(n 按回车键继续 .);getchar();fclose(fp);v
8、oid SearchStr(char s,char str,int count) /查找字符串中字符的个数和每个字符出现的次数 int i,j,k=0;for(i=0;iN;i+) / 初始化每个字符出现的次数 counti=0;for(i=0;si;i+)for(j=0;jk;j+) / 在 str 中查找是否有该字符 if(strj=si)countj+; break;if(j=k) / 在 str 中无该字符,将其存入最后一个单元 strk=si;countk+; strk=0; / 将字符串结尾置 0 n=k; /将实际的字符个数作为叶子节点个数存入 nvoid SelectMin(H
9、FMTree HT,int k,HFMTree *HT1,HFMTree *HT2)/查找哈夫曼链表中两个权值最小的节点int i,min;HFMTree p;min=32767; for(i=0,p=HT;inext)if(p-weightParent=0)min=p-weight;*HT1=p; min=32767;for(i=0,p=HT;inext)if(p-weightParent=0&p!=*HT1) / 令第二个最小的节点不等于第一个节点 min=p-weight;*HT2=p;void CreatHFMTree(HFMTree *HT,int count)/创建哈夫曼树int
10、i;HFMTree p,HT1,HT2; /HT1 ,HT2 分别存放权值最小和次小的节点的位置 p=*HT=(HFMTree)malloc(sizeof(HFMNode);p-next=p-LChild=p-RChild=p-Parent=NULL; / 初始化哈夫曼链表且有 2n-1 个节点 for(i=1;inext=(HFMTree)malloc(sizeof(HFMNode);p=p-next;p-next=p-LChild=p-RChild=p-Parent=NULL;for(i=0,p=*HT;iweight=counti;p=p-next;for(i=n;iParent=HT2
11、-Parent=p;p-LChild=HT1;p-RChild=HT2;p-weight=HT1-weight+HT2-weight; / 将两个节点的权值相加存入最后一个节点中 p=p-next; /p 指向下一个没有存储权值的节点void HFMCode(HFMTree HT,CodeNode HC,char str)/从每个叶子节点开始,利用哈夫曼树对每个字符进行编码,最终建立一个哈夫曼表 int i;HFMTree q,p=HT;for(i=0;in;i+) / 将字符存入哈夫曼编码结构体数组的字符单元中HCi.ch=stri;HCi.coden-1=0; / 初始化编码的最后一位fo
12、r(i=0;iParent;q=q-Parent) / 判断 q 所指向的节点,左孩子置 0,右孩子置 1 if(q=q-Parent-LChild)HCi.code-HCi.start=0;else HCi.code-HCi.start=1;p=p-next; / 判断下一个叶子节点void TotalCoding(char s,CodeNode HC,char code)/利用哈夫曼编码表对整个字符串进行编码int i,j;code0=0; / 编码数组初始化for(i=0;si;i+) / 将每个字符在哈夫曼编码表中对应的编码存入存放总编码的数组中 for(j=0;jParent;roo
13、t=root-Parent); / 用 root 指向哈夫曼树的根结点 for(i=0,p=root;codei;i+) / 从根结点开始按编码顺序访问树if(codei=0)p=p-LChild;else p=p-RChild;if(p-LChild=NULL&p-RChild=NULL) / 到根节点时将该节点对应的字符输出 for(j=0,q=HT;q!=p;q=q-next,j+);sk+=strj;p=root; / 回溯到根结点sk=0; / 解码完毕,在字符串最后一个单元存入 0void Coding(char s,char str,char code,int count,HFM
14、Tree *HT,CodeNode HC)clearscreen();printf(n 打开存放字符串的文件 .nn);Open(s); / 打开源码文件SearchStr(s,str,count); /查找字符串中不同的字符及其出现的次数CreatHFMTree(HT,count); / 用每个字符出现的次数作为叶子节点的权值建立哈夫曼树 HFMCode(*HT,HC,str); / 利用哈夫曼树对每个叶子节点进行编码,存入编码表中 TotalCoding(s,HC,code); / 利用编码表对字符串进行最终编码printf(n 读入的字符串为 :n); puts(s);printf(n
15、最终的哈夫曼编码是 :n); puts(code);printf(n 保存编码 ,);Save(code); /保存最终的哈夫曼编码void TransCode(char code,char str,char ss,HFMTree *HT,CodeNode HC) clearscreen();printf(n 打开编码的文件 .nn);Open(code); / 打开编码文件DeCoding(code,*HT,str,ss); / 将编码进行解码存入字符串数组 ss 中printf(n 得到的最终字符串为 :n);puts(ss);printf(n 保存译码, );Save(ss); /保存译
16、码后的字符串 int main() /主函数char sM,ssM; /定义字符串数组,s存放将要编码的字符串, ss存解码后的字符串char strN; /存放输入的字符串中 n 个不同的字符int countN; / 存放 n 个不同字符对应的在原字符串中出现的次数char codeM; / 存放最终编码完成后的编码char choice;HFMTree HT; / 定义一个哈夫曼树的链表CodeNode HCN; / 定义一个哈夫曼编码表的数组,存放每个字符对应的哈夫曼编码 doclearscreen(); printf(nn);printf( * printf( * *n);print
17、f( * 1. 编码。 printf( * 2. 译码。 printf( * 0. 退出。 printf( * *n);printf( * *n);哈夫曼树*n);*n);*n);*n);printf( * *n);scanf(%c,&choice);getchar(); switch(choice)case 1: Coding(s,str,code,count,&HT,HC);break; / 对字符串进行编码 case 2: TransCode(code,str,ss,&HT,HC);break; / 对编码进行解码 case 0: break;default : printf( 输入错误!请重新输入! n);while(choice!=0);
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1