哈弗曼压缩文件.docx
- 文档编号:30222269
- 上传时间:2023-08-07
- 格式:DOCX
- 页数:12
- 大小:16.41KB
哈弗曼压缩文件.docx
《哈弗曼压缩文件.docx》由会员分享,可在线阅读,更多相关《哈弗曼压缩文件.docx(12页珍藏版)》请在冰豆网上搜索。
哈弗曼压缩文件
哈弗曼压缩文件
#include
#include
#include
#include
#include
#defineFALSE0
#defineTRUE1
#defineSIZE256
typedefstruct
{//哈弗曼树的结构体
unsignedchardata;
intweight,LChild,RChild,parent;
}HTNode,*HuffmanTree[1000];
typedefstructNode
{//哈弗曼编码的结构体
unsignedchardata;
char*elem;
structNode*next;
}Node,*HuffmanCode[SIZE];
typedefstructStackNode
{//栈的结构体
chardata;
structStackNode*next;
}StackNode,*LinkStack;
voidInitStack(LinkStack*top)
{//栈的初始化
(*top)=(LinkStack)malloc(sizeof(StackNode));
(*top)->next=NULL;
}
intPush(LinkStacktop,charx)
{//进栈
StackNode*temp;
temp=(LinkStack)malloc(sizeof(StackNode));
if(temp==NULL)
return(FALSE);//申请失败
temp->data=x;
temp->next=top->next;
top->next=temp;
return(TRUE);
}
intPop(LinkStacktop,char*x)
{//出栈
StackNode*temp;
temp=top->next;
if(temp==NULL)
return(FALSE);
top->next=temp->next;
*x=temp->data;
free(temp);
return(TRUE);
}
voidFileEnterStack(LinkStacktop)
{//文件进栈
FILE*f;
unsignedchara;intp;
f=fopen("source.txt","rt");//打开要压缩的文件
if(f==NULL)
{
printf("文件打开失败!
");
getch();
exit
(1);
}
while(!
feof(f))
{
a=fgetc(f);
p=Push(top,a);//进站
if(p==0)
exit
(1);
}
fclose(f);
}
voidCreatWeight(int*w,LinkStacktop,int*n,char*c)
{//计算文件各个字符频率作为权值
intk=0,i=0,q;
LinkStacktop2;
chara,b;
*n=0;
while(Pop(top,&a))
{
(*n)++;
c[k]=a;
InitStack(&top2);
w[i]=1;
while(Pop(top,&b))
{
if(b!
=a)
{
q=Push(top2,b);
if(q==0)
exit
(1);
}
elsew[i]++;
}
top=top2;
k++;
i++;
}
}
voidSelect(HuffmanTreeht,intend,int*s1,int*s2)
{//选出最小的俩个
inti;
intmin1,min2;
min1=min2=SIZE;
for(i=1;i<=end;i++)
{
if(ht[i]->parent==0&&ht[i]->weight { *s1=i; min1=ht[i]->weight; } } for(i=1;i<=end;i++) { if(ht[i]->parent==0&&(i! =*s1)&&(ht[i]->weight { *s2=i; min2=ht[i]->weight; } } } voidCrtHuffmanTree(HuffmanTreeht,int*w,intn,char*c) {//哈弗曼数的建立 ints1,s2; inti,m; if(n==2) return; for(i=1;i<=n;i++) { ht[i]=(HTNode*)malloc(sizeof(HTNode)); ht[i]->data=c[i]; ht[i]->weight=w[i]; ht[i]->parent=ht[i]->LChild=ht[i]->RChild=0; } m=2*n-1; for(i=n+1;i<=m;i++) { ht[i]=(HTNode*)malloc(sizeof(HTNode)); ht[i]->data=''; ht[i]->weight=ht[i]->parent=ht[i]->LChild=ht[i]->RChild=0; } for(i=n+1;i<=m;i++) { Select(ht,i-1,&s1,&s2); ht[i]->weight=ht[s1]->weight+ht[s2]->weight; ht[s1]->parent=i; ht[s2]->parent=i; ht[i]->LChild=s1; ht[i]->RChild=s2; } } voidCrtHuffmanCode(HuffmanTreeht,HuffmanCodehc,intn) {//哈弗曼编码的确立 char*cd; intstart,c,p,i; if(n==1) { hc[1]->data=ht[1]->data; hc[1]->elem=(char*)malloc(2*sizeof(char)); hc[1]->elem[0]='1'; hc[1]->elem[1]='\0'; return; } cd=(char*)malloc((n+1)*sizeof(char)); cd[n-1]='\0'; for(i=1;i<=n;i++) { hc[i]=(Node*)malloc(sizeof(Node)); start=n-1; c=i; p=ht[i]->parent; while(p! =0) { --start; if(ht[p]->LChild==c) cd[start]='0'; else cd[start]='1'; c=p; p=ht[p]->parent; } hc[i]->data=ht[i]->data; hc[i]->elem=(char*)malloc((n-start)*sizeof(char)); strcpy(hc[i]->elem,&cd[start]); } free(cd); } voidPrintCode(HuffmanCodehc,intn) {//打印出哈弗曼编码 inti; printf("n=%d\n",n); for(i=1;i<=n;i++) { printf("字符: %c编码: %s\n",hc[i]->data,hc[i]->elem); } } charSwap(char*elem) {//进制转化 inti,leap; doublearray=0; unsignedcharc; for(i=0;i<8;i++) { if(elem[i]=='0') leap=0; elseleap=1; array+=leap*pow(2,7-i); } c=(char)array; returnc; } voidCompressFile(HuffmanCodehc,HuffmanTreeht,intn) {//压缩文件 FILE*f,*fe; unsignedcharc,*temp,b; inti,j,p,length,k=0,q=0,hulength=0,num=0; temp=(char*)malloc(sizeof(char)*9); temp[8]='\0'; fe=fopen("source","rt"); f=fopen("code.txt","wt"); for(i=1;i<=n;i++) hulength+=(ht[i]->weight*strlen(hc[i]->elem)); b=(char)((8-(hulength%8))%8); num=(hulength+b)/8; printf("字节总数: %d\n",num); //b=(char)num; fwrite(&num,sizeof(int),1,f); printf("补零个数: %d\n",(8-(hulength%8))%8); fwrite(&b,1,1,f);//文件末尾补零个数 b=(char)n; printf("叶节点数: %d\n",n); fwrite(&b,1,1,f); for(i=1;i<=n;i++) { fwrite(&hc[i]->data,1,1,f); fwrite(&ht[i]->weight,sizeof(int),1,f); printf("字符: %c叶节点权值: %d\n",hc[i]->data,ht[i]->weight); free(ht[i]);//释放哈弗曼树 } while(! feof(fe)) { c=fgetc(fe); for(i=1;i<=n;i++) if(c==hc[i]->data) { length=strlen(hc[i]->elem); for(p=k,j=k;j { temp[p]=hc[i]->elem[q]; if(j==7) { b=Swap(temp); fwrite(&b,1,1,f); p=-1; } } q=0; k=j%8; break; } } if(j<8) { for(i=j;i<=7;i++) temp[i]='0';//补零 b=Swap(temp); fwrite(&b,1,1,f); } //fputc('-1',f); fclose(fe); fclose(f); free(temp); //for(i=1;i<=n;i++); //free(hc[i]);//释放哈弗曼编码 } intmain() { chara[SIZE]; intk[SIZE],m; LinkStacks; HuffmanTreehu; HuffmanCodehd; InitStack(&s); FileEnterStack(s); CreatWeight(k,s,&m,a); CrtHuffmanTree(hu,k,m-1,a); CrtHuffmanCode(hu,hd,m-1); PrintCode(hd,m-1); CompressFile(hd,hu,m-1); return0; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 哈弗曼 压缩文件