logo资料库

霍夫曼编解码的C程序源代码.doc

第1页 / 共16页
第2页 / 共16页
第3页 / 共16页
第4页 / 共16页
第5页 / 共16页
第6页 / 共16页
第7页 / 共16页
第8页 / 共16页
资料共16页,剩余部分请下载后查看
实现霍夫曼编解码的 C 源程序如下:(验证结果见附图) #include #include #include #include #define N 16000 #define m 128 #define M 2*m-1 char CH[N]; char YW[N]; typedef char * Hcode[m+1]; //存放哈夫曼字符编码串的头指针的数组 typedef struct { //叶子结点个数,即字符总类数 //哈夫曼树的节点数 //记录原文字符数组 //记录译文字符数组 char a; int num; }dangenode; typedef struct { dangenode b[129]; int tag; }jilunode; typedef struct node { int weight; int parent; int Lchild; int Rchild; }htnode,hn[M]; //记录单个字符的类别和出现的次数 //统计原文出现的字符种类数 //结点权值 //双亲下标 //左孩子结点的下标 //右孩子的下标 //静态三叉的哈夫曼树的定义 /* 主函数 */ void main() { void jianliwenjian(); void luruyuanwen(); void min_2(hn ht,int n,int *tag1,int *tag2); /*建立文件函数声明*/ /*录入函数声明*/ /*选择权值最小的结点函数声明 void chuangjian(jilunode * jilu,hn ht,float gailv[128],int * ppt); /*建立哈弗曼函数声明 */ */ void bianma(jilunode * jilu,hn ht,Hcode hc,int n,int kk[129]); void bianmabaocun(Hcode hc,jilunode * jilu); void yiwen(Hcode hc,jilunode * jilu); void baocunyiwen(); /*编码函数声明*/ /*保存编码函数声明*/ /*译文函数声明*/ /*保存译文函数声明*/
/*读取译文函数声明*/ /*读取译文函数声明*/ /*读取译码函数声明*/ //定义用三叉链表方式实现的哈夫曼树 //定义存放哈夫曼字符编码串的头指针的数组 //定义存放字符种类数量的栈 void duquyiwen(); void duquyuanwen(); void duqubianma(); int a,c,tep=1,qqq,ss; int *ppt; int kk[129]; char ww; float abc1,gailv[m],sumc=0,jieguo=0,HH=0; ppt=&ss; hn humtree; Hcode hc; jilunode ji; jilunode *jilu; jilu=&ji; jilu->tag=0; while(tep) { printf(" printf("\n"); //取指针 //字符种类数标志初始化 $$$$$ 欢迎使用哈夫曼编码系统 $$$$$ \n"); printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $$$$$$\n"); printf("\n"); printf(" printf(" printf(" printf(" printf(" printf(" printf(" printf(" printf(" printf("\n"); 1--创建存贮原文件的文件\n"); 2--输入原文\n"); 3--对原文编码\n"); 4--对编码译码\n"); 5--输出原文\n"); 6--输出译码\n"); 7--输出译文\n"); 8--输出编码效率\n"); 0--退出\n"); printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 请输入服务选项(数字): $$$$$$$$$$$\n"); printf("\n"); printf(" a=0; scanf("%d",&a); getchar(); switch(a) { case 1: ");
case 2: //建立存储字符的文件 jianliwenjian(); printf("是否继续?(YES :1 ,NO :0 ):"); scanf("%d",&c); ww=getchar(); if(ww=='n') goto LABLE; system("cls"); break; //将原文录入到文件中 system("cls"); luruyuanwen(); printf("\n 注意:原文件将保存在名称为 yuanwen 的文件中!\n"); printf("\n 注意:文件保存在 yuanwen 的文件中!\n"); printf("是否继续?(YES :1,NO :0 ):"); scanf("%d",&c); ww=getchar(); if(ww=='n') goto LABLE; system("cls"); break; case 3: //创建哈夫曼树 //对哈夫曼树的叶子结点编码 system("cls"); chuangjian(jilu,humtree,gailv,ppt); printf("\n 各字符编码结果为:\n"); bianma(jilu,humtree,hc,jilu->tag,kk); printf("原文的编码为:\n"); printf("\n"); bianmabaocun(hc,jilu); printf("\n"); printf("\n 注意:原文的编码将保存在以名称为 yiwen 的文件中!\n"); printf("是否继续?(YES :1 ,NO :0 ):"); scanf("%d",&c); ww=getchar(); if(ww=='n') //保存编码 goto LABLE; system("cls"); break; case 4: system("cls"); printf("编码对应的译文为:\n"); yiwen(hc,jilu); baocunyiwen(); printf("\n 注意:译文将保存在以名称为 textfile 的文件中!\n"); printf("是否继续?(YES :1,NO :0):"); //对编码译码 //保存译文
scanf("%d",&c); ww=getchar(); if(ww=='n') goto LABLE; system("cls"); break; case 5: system("cls"); printf("原文为:\n"); duquyuanwen(); printf("是否继续?(YES :1,NO :0 ):"); scanf("%d",&c); ww=getchar(); if(ww=='n') //从文件中读取原文 goto LABLE; system("cls"); break; case 6: system("cls"); printf("原文的编码为:\n"); duqubianma(); printf("是否继续?(YES :1,NO :0):"); scanf("%d",&c); ww=getchar(); if(ww=='n') //从文件中读取编码 goto LABLE; system("cls"); break; case 7: system("cls"); printf("编码的译文为:\n"); duquyiwen(); printf("是否继续?(YES :1,NO :0 ):"); scanf("%d",&c); ww=getchar(); if(ww=='n') //从文件中读取译文 goto LABLE; system("cls"); break; case 8: system("cls"); for(qqq=1;qqq<=ss;qqq++) { sumc=sumc+(gailv[qqq]*kk[qqq]);
} printf("平均码长: %f",sumc); for(qqq=1;qqq<=ss-1;qqq++) { HH=HH-((gailv[qqq])*((log(gailv[qqq]))/(log(2)))); } printf("\n"); printf("信源熵为: %f",HH); jieguo=HH/sumc; printf("\n"); printf("编码效率为: %f",jieguo); printf("\n"); printf("是否继续?(YES :1,NO :0 ):"); scanf("%d",&c); ww=getchar(); if(ww=='n') goto LABLE; system("cls"); break; LABLE:case 0: system("cls"); printf("\n"); printf("\n"); printf("\n"); printf(" printf("\n"); printf(" printf("\n"); printf(" printf("\n"); printf("\n"); printf("\n"); printf("\n"); tep=0; break; system("cls"); printf(" printf("\n"); default: } } } 再见! "); BYEBYE!\n"); Welcome To See You Again!\n"); 选择错误!\n");
void jianliwenjian() { printf("现在建立文件,以存储原文:\n"); printf(" FILE *fp; if((fp=fopen("yuanwen","wb"))==NULL) { 文件建立中......\n"); printf("Cannot open file\n"); exit(0); //建立文件 } printf("文件已建立,名称为:yuanwen"); fclose(fp); //关闭文件 } void luruyuanwen() { //原文输入完后,将其保存到文件 yuanwen 中 //打开文件 char ch; FILE *fp; if((fp=fopen("yuanwen","wb"))==NULL) { printf("Cannot open file\n"); exit(0); } printf("请输入原文(结束标志为#)\n"); do { ch=getchar(); fputc(ch,fp); }while(ch!='#'); getchar(); fclose(fp); } //将字符保存到文件中 //判断结束 //接收回车命令符 //关闭文件 void min_2(hn ht,int n,int *tag1,int *tag2)//在建哈夫曼树的过程中,选择权值小的两 { //个结点 int i,min,s; min=N; for(i=1;i<=n;i++) if(ht[i].weight
min=ht[i].weight; *tag1=i; //记录权值最小的结点下标 } min=N; for(i=1;i<=n;i++) if(ht[i].weighttag;j++) { if(CH[i]==jilu->b[j].a) {
jilu->b[j].num++; break; } /* 统计每个符号的出现的次数,并记录到*jilu 中去 */ } if(j-1==jilu->tag&&CH[i]!=jilu->b[j-1].a) { jilu->tag++; jilu->b[jilu->tag].a=CH[i]; jilu->b[jilu->tag].num=1; } } } jilu->tag--; *ppt=jilu->tag; fclose(fp); printf("原文中的各字符统计状况如下:\n"); printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n"); for(i=1;i<=jilu->tag;i++) { //关闭文件 s++; printf("'%c'的个数为:%d if(s%4==0) printf("\n"); SUMF+=jilu->b[i].num; zong[i]=jilu->b[i].num; ",jilu->b[i].a,jilu->b[i].num); //每行放四个数据 /*统计字符总数*/ } printf("\n"); printf(" 源文件字符总数为 : %d",SUMF); printf("\n"); for(i=1;i<=jilu->tag;i++) /*概率统计*/ { /*打印字符总数*/ gailv[i]=zong[i]/(float)SUMF; printf("%c 字符出现的概率为: %f ",jilu->b[i].a,gailv[i]); } printf("\n"); for(i=1;i<=2*(jilu->tag)-1;i++) { if(i<=jilu->tag) { ht[i].weight=jilu->b[i].num; ht[i].Lchild=0; ht[i].parent=0; ht[i].Rchild=0; //初始化叶子结点权值 //初始化叶子结点左孩子 //初始化叶子结点父母 //初始化叶子结点右孩子
分享到:
收藏