实例介绍
【实例简介】
发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码。
(1)接收原始数据: 从终端读入字符集大小n,n个字符和n个权值,建立哈夫曼树,存于文件hfmtree.dat中。
(2)编码: 利用已建好的哈夫曼树(如不在内存,则从文件hfmtree.dat中读入)对文件中的正文进行编码,然后将结果存入文件codefile.dat中。
(3)译码: 利用已建好的哈夫曼树将文件codefile.dat中的代码进行译码,结果存入文件textfile.dat 中。
(4)打印编码规则:即字符与编码的一一对应关系。
(5)打印哈夫曼树:将已在内存中的哈夫曼树以直观的方式显示在终端上。
【实例截图】
【核心代码】
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <malloc.h>
#define NULL 0
//#define OK 1
//#define ERROR 0
//#define OVERFLOW -2
#define MAX_NUM 10000
#define MAX 60
int j=0;
typedef int Status;
typedef char **HuffmanCode;
typedef struct{
unsigned int weight;//字符对应的权值
unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree;//此处定义了哈夫曼树节点的数据类型。提供给Huffman使用
typedef struct{
HuffmanTree HT;
char *c;//存放将要建立哈夫曼树的字符
int longth;//字符的大小,即开始第一步输入的一个整数
HuffmanCode HC;//存放对应的哈夫编码即对应的01代码
}Huffman;
void Select(HuffmanTree HT,int end,int *s1,int *s2)
//把输入的字符按权值从小到大排序,挑出最小权值供HuffmanCoding()调用
//并且根节点的权值等于他的左右孩子的权值和
//min2是在剩下的字符中挑出的最小的劝值的字符
{
int i;
int min1=MAX_NUM;//min1是根节点的权值
int min2;//min2是在剩下的字符中挑出的最小的权值的字符
for (i=1;i<=end;i )
{
if (HT[i].parent==0&&HT[i].weight<min1)
{
*s1=i;
min1=HT[i].weight;
}
}
min2=MAX_NUM;
for(i=1;i<=end;i )
{
if(HT[i].parent==0&&(*s1!=i)&&min2>HT[i].weight)
{
*s2=i;
min2=HT[i].weight;
}
}
//test printf("qqqqq%d\nWWWWW%d\n",min1,min2);
}
Huffman HuffmanCoding(Huffman Hfm)//将输入的字符以及他的权值,按照哈夫曼规则建立2叉树
{
/*---------------------------------*/
int i,n,m,s1,s2,start;
int c,f;
char *cd;
n=Hfm.longth;
if(n<=1) return Hfm;
m=2*n-1;
for(i=n 1;i<=m; i)
{
Select(Hfm.HT,i-1,&s1,&s2);
Hfm.HT[s1].parent=i;
Hfm.HT[s2].parent=i;
Hfm.HT[i].lchild=s1;
Hfm.HT[i].rchild=s2;
Hfm.HT[i].weight=Hfm.HT[s1].weight Hfm.HT[s2].weight;
//构造哈夫曼树时候,根节点的权值等于他的左右孩子权值和
//test printf("ht%d\ns1--%d\ns2--%d", Hfm.HT[i].weight,s1,s2);
}
/*------------------------------------------*/
Hfm.HC=(HuffmanCode)malloc((n 1)*sizeof(char *));
cd=(char *)malloc(n*sizeof(char));
cd[n-1]='\0';
//中间变量用来存储字符对应的哈夫曼01编码
for(i=1;i<=n; i)
{
start=n-1;
for(c=i,f=Hfm.HT[i].parent;f!=0;c=f,f=Hfm.HT[f].parent)
{
if(c==Hfm.HT[f].lchild) cd[--start]='0';
else cd[--start]='1';
}
Hfm.HC[i]=(char *)malloc((n-start)*sizeof(char));
strcpy(Hfm.HC[i],&cd[start]);
//将cd[]的值存储到变量Hfm.HC[i]中
//该变量在Huffman数据类型中有定义
}
free(cd);
return Hfm;
}
Huffman InputHuffman(Huffman Hfm)//接收原始数据: 从终端读入字符集大小n,n个字符和n个权值,
//建立哈夫曼树,存于文件hfmtree.dat中。供InitHuffman()函数调用
{
int i,n;
printf("\n\n\t\t********************构造哈夫曼树*********************\n");
printf("\t字符以及它的权值,数据将保存到同名目录下的'hfmTree.dat'\n");
printf("请输入字符的个数: ");
scanf("%d",&n);
Hfm.HT=(HuffmanTree)malloc((2*n)*sizeof(HTNode));
Hfm.c=(char *)malloc((n 1)*sizeof(char));
for(i=1;i<=n;i )//接收数据,并初始话,左右孩子节点赋0
{
printf("请输入字符\n: ");
scanf("%s",&Hfm.c[i]);
printf("请输入他的权值\n: ");
scanf("%d",&Hfm.HT[i].weight);
Hfm.HT[i].parent=0;
Hfm.HT[i].lchild=0;
Hfm.HT[i].rchild=0;
}
for(;i<=2*n-1; i)
{
Hfm.HT[i].weight=0;
Hfm.HT[i].parent=0;
Hfm.HT[i].lchild=0;
Hfm.HT[i].rchild=0;
}
Hfm.longth=n;
return Hfm;
}
Huffman InitHuffman(Huffman Hfm)//初始化哈夫曼树,调用InputHuffman(),HuffmanCoding()函数
//将数据存入文件,如果文件以存在,那么直接读取数据,进行哈夫编码
{
int n,i;
FILE *fp;
fp=fopen("hfmTree.dat","rt");
if(fp==NULL)
{
Hfm=InputHuffman(Hfm);
fp=fopen("hfmTree.dat","wt");
fprintf(fp,"%d\n",Hfm.longth);
for(i=1;i<=Hfm.longth;i )
fprintf(fp,"%c %d",Hfm.c[i],Hfm.HT[i].weight);
rewind(fp);
}
else
{
fscanf(fp,"%d\n",&n);
Hfm.c=(char *)malloc((n 1)*sizeof(char));
Hfm.HT=(HuffmanTree)malloc((2*n)*sizeof(HTNode));
for(i=1;i<=n;i )
fscanf(fp,"%s %d",&Hfm.c[i],&Hfm.HT[i].weight);
for(i=1;i<=n;i )
{
Hfm.HT[i].parent=0;
Hfm.HT[i].lchild=0;
Hfm.HT[i].rchild=0;
}
for(;i<=2*n-1; i)
{
Hfm.HT[i].weight=0;
Hfm.HT[i].parent=0;
Hfm.HT[i].lchild=0;
Hfm.HT[i].rchild=0;
}
Hfm.longth=n;
}
fclose(fp);
Hfm=HuffmanCoding(Hfm);
return Hfm;
}
void Output(Huffman Hfm)
//输出哈夫曼树,字符,权值,以及它对应的编码
{
int i,n;
n=Hfm.longth;
printf("\n\n******************它的编码规则****************\n\n");
for(i=1;i<=n;i )
{
printf("\n");
printf("字符: %c\t",Hfm.c[i]);
printf("权值: %d\t",Hfm.HT[i].weight);
printf("对应的哈夫曼编码: ");
puts(Hfm.HC[i]);
}
printf("\n\n******************打印哈夫曼树****************\n\n");
for(i=n;i>=1;i--)
{ if(n==i)
{ printf("\t\t*\n\n");
printf("\t%c\t\t*\n\n",Hfm.c[i]);
}
else if(i!=2&&i!=1)
{
for(j=0;j<=n-i;j )
printf("\t");
printf("%c\t\t*\n\n",Hfm.c[i]);
}
else if(i==2)
{ for(j=0;j<=n-i;j )
printf("\t");
printf("%c\t\t%c\n\n",Hfm.c[i],Hfm.c[1]);
}
else if(i==1)
printf("\n\n");
}
}
void Encoding(Huffman Hfm)
//编码: 利用已建好的哈夫曼树(如不在内存,则从文件hfmtree.dat中读入)
//对文件中的正文进行编码,然后将结果存入文件codefile.dat中。
//如果正文中没有要编码的字符,则键盘读入并存储到ToBeTran文件中
//读入ToBeTran中将要编码的内容,将编码好的哈夫曼编码存储到CodeFile中
{
int i=0,j=0,n;
char ch[MAX];
FILE *fp,*ffp;
n=Hfm.longth;
printf("\n\n*******************编码**************************\n\n");
if((ffp=fopen("ToBeTran.dat","rt"))==NULL)
{
printf("\n请输入要进行编码的句子: ");
scanf("%s",&ch);
printf("\n");
fp=fopen("CodeFile.dat","wt ");
}
else
{
fscanf(ffp,"%s",ch);
fclose(ffp);
}
while(ch[j])
{
for(i=1;i<=n;i )
if(ch[j]==Hfm.c[i])
{
printf("%s",Hfm.HC[i]);
fprintf(fp,"%s",Hfm.HC[i]);
break;
}
j ;
}
rewind(fp);
fclose(fp);
}
void Decoding(Huffman Hfm)
//译码: 利用已建好的哈夫曼树将文件codefile.dat
//中的代码进行译码,结果存入文件textfile.dat 中
{
HuffmanTree p;
int i,n;
int j=0;
char d[50];
FILE *fp;
n=Hfm.longth;
printf("\n\n******************译码************************\n\n");
if((fp=fopen("CodeFile.dat","rt"))==NULL)
{
printf("输入哈夫曼码进行译码\n:");
scanf("%s",&d);
}
else
{
fscanf(fp,"%s",d);
fclose(fp);
}
printf("\nThe file is : ");
fp=fopen("TextFile.dat","wt ");
while(d[j])
{
p=&Hfm.HT[2*n-1];
while(p->lchild||p->rchild)
{
if(d[j]=='0')
{ i=p->lchild; p=&Hfm.HT[i]; }
else
{ i=p->rchild; p=&Hfm.HT[i]; }
j ;
}\
printf("%c",Hfm.c[i]);
fprintf(fp,"%c",Hfm.c[i]);
}
fclose(fp);
}
int main()
{
Huffman Hfm;
char choice='a';
Hfm=InitHuffman(Hfm);
while(choice!='q')
{
printf("\n\n\n\t\t*************************************\n\n");
printf("\t\t\ta. 编码:\n\n");
printf("\t\t\tb. 译码:\n\n");
printf("\t\t\tc. 打印哈夫曼树以及它的编码规则:\n\n");
printf("\t\t\tq. 退出...\n\n");
printf("\n\t\t************************************\n\n");
printf("请输入你的选择\n: ");
scanf("%s",&choice);
switch(choice)
{
case 'a':
Encoding(Hfm);
printf("\n\n*******Please enter anykey to continue*******\n");
getch(); break;
case 'b':
Decoding(Hfm);
printf("\n\n*******Please enter anykey to continue********\n");
getch(); break;
case 'c':
Output(Hfm);
printf("\n\n*******Please enter anykey to continue********\n");
getch(); break;
case 'q':
break;
default:
printf(" 选择错误!\n Please enter anykey to choice again!\n");
getch(); break;
}
}
return 0;
}
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论