#include <stdio.h> #include <string.h> #include <stdlib.h> #include <conio.h> struct head { unsigned char b; //记录字符在数组中的位置 long count; //字符出现频率(权值) long parent,lch,rch; //定义哈夫曼树指针变量 char bits[256]; //定义存储哈夫曼编码的数组 } header[512],tmp; /*压缩*/ void compress() { char filename[255],outputfile[255],buf[512]; unsigned char c; long i,j,m,n,f; long min1,pt1,flength,length1,length2; double div; FILE *ifp,*ofp; getchar(); printf("\t请您输入需要压缩的文件:"); gets(filename); ifp=fopen(filename,"rb"); if(ifp==NULL) { printf("\n\t文件打开失败!\n\n"); return; } printf("\t请您输入压缩后的文件名:"); gets(outputfile); ofp=fopen(outputfile,"wb"); if(ofp==NULL) { printf("\n\t压缩文件失败!\n\n"); return; } flength=0; while(!feof(ifp)) { fread(&c,1,1,ifp); header[c].count++; //字符重复出现频率+1 flength++; //字符出现原文件长度+1 } flength--; length1=flength; //原文件长度用作求压缩率的分母 header[c].count--; for(i=0; i<512; i++) { if(header[i].count!=0) header[i].b=(unsigned char)i; /*将每个哈夫曼码值及其对应的ASCII码存放在一维数组header[i]中, 且编码表中的下标和ASCII码满足顺序存放关系*/ else header[i].b=0; header[i].parent=-1; header[i].lch=header[i].rch=-1; //对结点进行初始化 } for(i=0; i<256; i++) //根据频率(权值)大小,对结点进行排序,选择较小的结点进树 { for(j=i+1; j<256; j++) { if(header[i].count<header[j].count) { tmp=header[i]; header[i]=header[j]; header[j]=tmp; } } } for(i=0; i<256; i++) if(header[i].count==0) break; n=i; //外部叶子结点数为n个时,内部结点数为n-1,整个哈夫曼树的需要的结点数为2*n-1. m=2*n-1; for(i=n; i<m; i++) //构建哈夫曼树 { min1=999999999; //预设的最大权值,即结点出现的最大次数 for(j=0; j<i; j++) { if(header[j].parent!=-1)
09-16