哈夫曼编码与解码C语言知识讲解.docx

上传人:b****5 文档编号:11794450 上传时间:2023-04-02 格式:DOCX 页数:10 大小:17.13KB
下载 相关 举报
哈夫曼编码与解码C语言知识讲解.docx_第1页
第1页 / 共10页
哈夫曼编码与解码C语言知识讲解.docx_第2页
第2页 / 共10页
哈夫曼编码与解码C语言知识讲解.docx_第3页
第3页 / 共10页
哈夫曼编码与解码C语言知识讲解.docx_第4页
第4页 / 共10页
哈夫曼编码与解码C语言知识讲解.docx_第5页
第5页 / 共10页
点击查看更多>>
下载资源
资源描述

哈夫曼编码与解码C语言知识讲解.docx

《哈夫曼编码与解码C语言知识讲解.docx》由会员分享,可在线阅读,更多相关《哈夫曼编码与解码C语言知识讲解.docx(10页珍藏版)》请在冰豆网上搜索。

哈夫曼编码与解码C语言知识讲解.docx

哈夫曼编码与解码C语言知识讲解

 

哈夫曼编码与解码C语言

#include"stdio.h"/*I/O函数*/

#include"stdlib.h"/*其他库函数声明*/

intnum;/*记录结点数*/

intcodenum=0;/*已经获得的编码个数*/

charfilename[20]="";/*存储文件名*/

typedefstruct/*哈夫曼结点存储结构*/

{

charch;/*结点字符*/

intw;/*结点权值*/

intlchild,rchild;/*左右孩子的数组下标*/

}HafuNode,*HafuTree;

HafuTreeht;/*声明一个指向树结点到指针*/

typedefstruct

{

charch;/*叶子结点字符*/

charcodestr[20];/*字符编码*/

}HafuCode;

HafuCodecode[27];/*用于存放对应字符到哈夫曼编码*/

voidInitHafuArry()

{/*导入文件计算权值,生成只含有叶子结点的HafuNode数组*/

intj,i,k;

HafuNodetmpht;

FILE*fp;/*定义一指向打开文件的指针*/

charch;/*用于存储一个字母*/

charlocation[30]="D:

\\";

ht=(HafuTree)malloc(53*sizeof(HafuNode));/*为哈夫曼数分配内存空间*/

if(ht==NULL)return;

for(i=0;i<53;i++)/*初始化所以的数据单元,每个单元自成一棵树*/

{

ht[i].w=0;/*权值初始化为0*/

ht[i].lchild=ht[i].rchild=-1;/*左右子为空*/

}

num=0;

printf("Filename:

");

scanf("%s",filename);

strcat(location,filename);

fp=fopen(location,"r");

if(!

fp)/*返回1时即存在文件*/

{

printf("OpenError");

return;

}

while(!

feof(fp))/*没到结尾时返回0*/

{

ch=fgetc(fp);

if(ch==''||ch<='z'&&ch>='a'||ch<='Z'&&ch>='A')

{

printf("%c",ch);

if(ch=='')ch='#';

for(j=0;j

{

if(ht[j].ch==ch)

{

break;

}

}

if(j==num)/*找到新字符*/

{

ht[num].ch=ch;/*将新字符存入并将权值加1*/

ht[num].w++;

num++;

}

else

{

ht[j].w++;/*将已有字符权值加1*/

}

}

}fclose(fp);

printf("\n");

for(i=0;i

{

k=i;

for(j=i+1;j

{

if(ht[j].w

k=j;

}

if(k!

=i)/*如果权值最小的不是第i个元素则交换位置,将小的放到前面*/

{

tmpht=ht[i];

ht[i]=ht[k];

ht[k]=tmpht;

}

}

}

intCreateHafuman(HafuTreeht)

{/*在数组ht中生成哈夫曼数,返回根节点下标*/

inti,k,j,root;

HafuNodehfnode;

codenum=0;

for(i=0;i

{/*需生成num-1个结点*/

k=2*i+1;/*每次取最前面两个结点,其权值必定最小*/

hfnode.w=ht[k].w+ht[k-1].w;

hfnode.lchild=k-1;

hfnode.rchild=k;

for(j=num+i;j>k;j--)/*将新结点插入有序数组中*/

{

if(ht[j].w>hfnode.w)

{

ht[j+1]=ht[j];

}

elsebreak;

}

ht[j]=hfnode;

root=j;/*一直跟随新生成的结点,最后新生成的结点为根结点*/

}

returnroot;

}

voidGetHafuCode(HafuTreeht,introot,char*codestr)

{/*ht是哈夫曼树,root是根结点下标,codestr是来暂时存放叶子结点编码的,一开始为空*/

FILE*out;

intlen,i;

FILE*fp;/*定义一指向打开文件的指针*/

charch;/*用于存储一个字母*/

charlocation[30]="D:

\\";

if(ht[root].lchild==-1)

{/*遇到递归终点是叶子结点记录叶子结点的哈夫曼编码*/

code[codenum].ch=ht[root].ch;

strcpy(code[codenum].codestr,codestr);

codenum++;

}

else/*不是终点则继续递归*/

{

len=strlen(codestr);

codestr[len]='0';/*左分支编码是0*/

codestr[len+1]=0;/*向左孩子递归之前调整编码序列末尾加0,相当于加了个‘\0’(null)其十进制值是0,以便下次循环时添加字符,否则会被覆盖掉*/

GetHafuCode(ht,ht[root].lchild,codestr);/*向左递归*/

len=strlen(codestr);

codestr[len-1]='1';/*右分支编码为1,想右递归之前末尾编码0改为1*/

GetHafuCode(ht,ht[root].rchild,codestr);/*向右递归*/

len=strlen(codestr);

codestr[len-1]=0;/*左右孩子递归返回后,删除编码标记末尾*/

}

strcat(location,filename);

fp=fopen(location,"r");

if(!

fp)/*返回1时即存在文件*/

{

printf("OpenError");

return;

}

out=fopen("D:

\\code.txt","w+");

if(!

out)

{

/*printf("WriteError");*/

return;

}

while(!

feof(fp))/*没到结尾时返回0*/

{

ch=fgetc(fp);/*再打开源文件,对照哈夫曼编码译成编码*/

if(ch==''||ch<='z'&&ch>='a'||ch<='Z'&&ch>='A')

{if(ch=='')ch='#';/*如果是空格就用#号代替*/

for(i=0;i

{/*找到字符所对应到哈夫曼编码*/

if(ch==code[i].ch)

{/*将所得哈夫曼编码输出到文件中*/

fputs(code[i].codestr,out);

}

}

}

}

fclose(fp);/*关闭打开到两个文件*/

fclose(out);

}

voiddecodeHafuCode(HafuTreeht,introot)/*将哈夫曼编码翻译为明文*/

{

FILE*fp2;/*定义一指向打开文件的指针*/

charch;/*用于存储一个字母*/

intcurr=root;/*当前结点到下标*/

charfilename2[20]="";/*获得文件名*/

charlocation[30]="D:

\\";

printf("Filename:

");

scanf("%s",filename);

strcat(location,filename);

fp2=fopen(location,"r");

if(!

fp2)/*返回1时即存在文件*/

{

printf("OpenError2");

return;

}

printf("Code:

");

while(!

feof(fp2))/*没到结尾时返回0*/

{

ch=fgetc(fp2);

if(ch>='0'&&ch<='1')/*将编码过滤出来*/

{

printf("%c",ch);/*将密文输出显示*/

}

}

printf("\n");

rewind(fp2);/*将文件指针位置定位在开头*/

while(!

feof(fp2))/*没到结尾时返回0*/

{

ch=fgetc(fp2);

if(ch>='0'&&ch<='1')/*将编码过滤出来*/

{

if(ch=='0')/*如果为0则当前结点向左走*/

{

if(ht[curr].lchild!

=-1)

{

curr=ht[curr].lchild;/*若有左子则去左子*/

}

else

{

curr=root;/*没有则返回根结点*/

}

}

if(ch=='1')/*如果为1则当前结点向右走*/

{

if(ht[curr].rchild!

=-1)

{

curr=ht[curr].rchild;/*若有右子则去右子*/

}

else

{

curr=root;/*没有则返回根结点*/

}

}

if(ht[curr].lchild==-1&&ht[curr].rchild==-1)/*若为叶子结点则打印输出*/

{

printf("%c",ht[curr].ch=='#'?

'':

ht[curr].ch);

curr=root;/*回到根结点继续索引*/

}

}

}

fclose(fp2);

}

voidmain()

{introot;

inti;

charcodestr[20]="";

intcontrol;

/*显示菜单可选择编码、译码还是退出*/

printf("================Menu==============\n");

printf("chose1:

encode\n");

printf("chose2:

decode\n");

printf("chose3:

exit\n");

scanf("%d",&control);

while(control!

=3)/*只有没有选择退出就一直循环*/

{

if(control==1)/*选择编码选项*/

{

FILE*output;

charch;

InitHafuArry();/*初始化结点*/

root=CreateHafuman(ht);/*造一棵哈夫曼树*/

GetHafuCode(ht,root,codestr);/*根据哈夫曼树将明文译成密码*/

printf("Code:

");

output=fopen("D:

\\CODE.TXT","r");

if(!

output)/*返回1时即存在文件*/

{

printf("OpenError3");

continue;

}

while(!

feof(output))/*没到结尾时返回0*/

{

ch=fgetc(output);

if(ch>='0'&&ch<='1')/*将编码过滤出来*/

{

printf("%c",ch);/*将密文输出显示*/

}

}

fclose(output);/*将打开文件关闭*/

}

if(control==2)/*如果选择译码,则调用译码函数*/

{

decodeHafuCode(ht,root);

}

if(control==3)/*如果选择3则退出程序*/

{

exit(0);

}

/*若没有退出则继续打印菜单提示供选择*/

printf("\n\n================Menu==============\n");

printf("chose1:

encode\n");

printf("chose2:

decode\n");

printf("chose3:

exit\n");getch();

scanf("%d",&control);

}

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育 > 唐诗宋词

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1