您好,欢迎光临本网站![请登录][注册会员]  
文件名称: 哈夫曼树的相关程序,试验
  所属分类: C
  开发工具:
  文件大小: 8kb
  下载次数: 0
  上传时间: 2009-04-09
  提 供 者: dh198*****
 详细说明: 问题描述: 利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码,请设计这样的一个简单编/译码系统。 基本要求: (1)接收原始数据: 从终端读入字符集大小n,n个字符和n个权值,建立哈夫曼树,存于文件hfmtree.dat中。 (2)编码: 利用已建好的哈夫曼树(如不在内存,则从文件hfmtree.dat中读入)对文件中的正文进行编码,然后将结果存入文件codefile.dat中。 (3)译码: 利用已建好的哈夫曼树将文件codefile.dat中的代码进行译码,结果存入文件textfile.dat 中。 (4)打印编码规则:即字符与编码的一一对应关系。 (5)打印哈夫曼树:将已在内存中的哈夫曼树以直观的方式显示在终端上。 实现提示 构造哈夫曼树时使用静态链表作为哈夫曼树的存储。求哈夫曼编码,实质上就是在已建立的哈夫曼树中,从叶子结点开始,沿结点的双亲链域回退到根结点,每回退一步,就走过了哈夫曼树的一个分支,从而得到一位哈夫曼码值。由于一个字符的哈夫曼编码是从根结点到相应叶子结点所经过的路径上各分支所组成的0,1序列,因此先 得到的分支代码为所求编码的低位码,后得到的分支代码为所求编码的高位码。 #include #include #include #include #define NULL 0 #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].weightHT[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; } ...展开收缩
(系统自动生成,下载前可以参看下载内容)

下载文件列表

相关说明

  • 本站资源为会员上传分享交流与学习,如有侵犯您的权益,请联系我们删除.
  • 本站是交换下载平台,提供交流渠道,下载内容来自于网络,除下载问题外,其它问题请自行百度
  • 本站已设置防盗链,请勿用迅雷、QQ旋风等多线程下载软件下载资源,下载后用WinRAR最新版进行解压.
  • 如果您发现内容无法下载,请稍后再次尝试;或者到消费记录里找到下载记录反馈给我们.
  • 下载后发现下载的内容跟说明不相乎,请到消费记录里找到下载记录反馈给我们,经确认后退回积分.
  • 如下载前有疑问,可以通过点击"提供者"的名字,查看对方的联系方式,联系对方咨询.
 相关搜索: 哈夫曼
 输入关键字,在本站1000多万海量源码库中尽情搜索: