用哈夫曼树实现压缩解压.docx

上传人:b****8 文档编号:9868525 上传时间:2023-02-07 格式:DOCX 页数:20 大小:27.79KB
下载 相关 举报
用哈夫曼树实现压缩解压.docx_第1页
第1页 / 共20页
用哈夫曼树实现压缩解压.docx_第2页
第2页 / 共20页
用哈夫曼树实现压缩解压.docx_第3页
第3页 / 共20页
用哈夫曼树实现压缩解压.docx_第4页
第4页 / 共20页
用哈夫曼树实现压缩解压.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

用哈夫曼树实现压缩解压.docx

《用哈夫曼树实现压缩解压.docx》由会员分享,可在线阅读,更多相关《用哈夫曼树实现压缩解压.docx(20页珍藏版)》请在冰豆网上搜索。

用哈夫曼树实现压缩解压.docx

用哈夫曼树实现压缩解压

用哈夫曼树实现压缩解压

程序是用VC++编译完成的,可以完成对任意文件的压缩解压(为方便寻找,压缩出的文件与待压缩文件在同一文件夹中),但压缩文件夹还不可以,另外该程序还能打印出压缩时所建立的哈夫曼树及哈夫曼编码。

源代码如下:

#include<>

#include<>

#include<>

#include<>

typedefstructnode

{

longw;

shortp,l,r;

}htnode,*htnp;

typedefstructhuffman_code

{

unsignedcharlen;

unsignedchar*codestr;

}hufcode;

typedefchar**huffmancode;

intinitial_files(char*source_filename,FILE**inp,char*obj_filename,FILE**outp);

char*create_filename(char*source_filename,char*obj_filename);

intcompress(char*source_filename,char*obj_filename);

longfrequency_data(FILE*in,longfre[]);

intsearch_set(htnpht,intn,int*s1,int*s2);

intcreate_hftree(longw[],intn,htnodeht[]);

intencode_hftree(htnphtp,intn,hufcodehc[]);

unsignedcharchars_to_bits(constunsignedcharchars[8]);

intwrite_compress_file(FILE*in,FILE*out,htnpht,hufcodehc[],char*source_filename,longsource_filesize);

intdecompress(char*source_filename,char*obj_filename);

voidget_mini_huffmantree(FILE*in,shortmini_ht[][2]);

intwrite_decompress_file(FILE*in,FILE*mini_ht[][2],longbits_pos,longobj_filesize);

intd_initial_files(char*source_filename,FILE*obj_filename,FILE**outp);

main()

{

ints;

charfilename[10];

system("color3F");

printf("

***************************************\n");

printf("*

*\n");

printf("*1.—————

out,short

**inp,char

菜单:

压缩——

*\n");

*\n");

退出

printf("*0.———

————*\n");

printf("***************************************\n");

scanf("%d",&s);

while(s!

=0)

{

getchar();

switch(s)

{

case1:

puts("请输入待压缩文件路径:

");

gets(filename);

compress(filename,NULL);

break;

case2:

puts("请输入待解压文件路径:

");

gets(filename);

decompress(filename,NULL);break;

default:

printf("指令错误!

请重新输入指令:

\n");

}

puts("");

printf("

***************************************\n");

printf("*菜单:

*\n");

printf("*1.——————压缩——————*\n");

printf("*2.—————-解压缩—

————-*\n");

printf("*0.——————退出—

—————*\n");

printf("

***************************************\n");

scanf("%d",&s);

}

}

intinitial_files(char*source_filename,FILE**inp,char*obj_filename,FILE**outp)

{

if(fopen(source_filename,"rb")==NULL)

{

return-1;

}

if(obj_filename==NULL)

{

if((obj_filename=(char*)malloc(256*sizeof(char)))==NULL)

{

return-1;

}create_filename(source_filename,obj_filename);

}

if(strcmp(source_filename,obj_filename)==0)

{

return-1;

}

printf("待压缩文件:

%s,压缩

件:

%s\n",source_filename,obj_filename);

if((*outp=fopen(obj_filename,"wb"))==NULL)

return-1;

}

if((*inp=fopen(source_filename,"rb"))==NULL)

{

return-1;

}

free(obj_filename);

return0;

}

char*create_filename(char*source_filename,char*obj_filename){

char*temp;if((temp=strrchr(source_filename,'.'))==NULL)

{

strcpy(obj_filename,source_filename);strcat(obj_filename,".zip");

}

else

{

strncpy(obj_filename,source_filename,temp-source_filename);

obj_filename[temp-source_filename]='\0';

strcat(obj_filename,".zip");

}

returnobj_filename;

}

intcompress(char*source_filename,char*obj_filename)

{

FILE*in,*out;

charch;

interror_code,i,j;

floatcompress_rate;

hufcodehc[256];

htnodeht[256*2-1];

longfrequency[256],source_filesize,obj_filesize=0;

error_code=initial_files(source_filename,&in,obj_filename,&out);

if(error_code!

=0)

{

puts("文件打开失败!

请重新输入文件路径:

");

returnerror_code;

source_filesize=frequency_data(in,frequency);printf("文件大小%ld字节\n",source_filesize);error_code=create_hftree(frequency,256,ht);if(error_code!

=0)

{

puts(”建立哈夫曼树失败!

");

returnerror_code;

}

error_code=encode_hftree(ht,256,hc);

if(error_code!

=0)

{

puts("建立哈夫曼编码失败!

”);

returnerror_code;

}

for(i=0;i<256;i++)obj_filesize+=frequency[i]*hc[i].len;

obj_filesize=obj_filesize%8==0?

obj_filesize/8:

obj_filesize/8+1;

for(i=0;i<256-1;i++)

obj_filesize+=2*sizeof(short);obj_filesize+=strlen(source_filename)+1;

obj_filesize+=sizeof(long);

obj_filesize+=sizeof(unsignedint);

compress_rate=(float)obj_filesize/source_filesize;

printf("压缩文件大小:

%ld字节,压缩比

例:

%.2lf%%\n",obj_filesize,compress_rate*100);

error_code=write_compress_file(in,out,ht,hc,source_filename,source_file

size);

if(error_code!

=0)

{

puts("写入文件失败!

");

returnerror_code;

}

puts("压缩完成!

");

puts("");

puts(”是否打印该文件中字符对应的huffman树及编码?

”);

puts("PleaseinputYORN");

do{

scanf("%s",&ch);

switch(ch)

case'Y':

puts(”以下是哈夫曼树:

”);

for(i=256;i<256*2-2;i++)

{

if(ht[i].w>0)

printf("%-10d%-10d%-10d%-10d%-10d\n",i,ht[i].w,ht[i].p,ht[i].l,ht[i].r);

}

puts(”以下是哈夫曼编码:

”);

for(i=0;i<256;i++)

{

if(frequency[i]==0)

i++;

else

{

printf("%d\t",frequency[i]);

for(j=0;j

printf("%d",hc[i].codestr[j]);

printf("\n");

}

}

break;case'N':

break;

default:

\n");

printf("指令错误!

请重新输入指令:

}

}while(ch!

='Y'&&ch!

='N');fclose(in);

fclose(out);for(i=0;i<256;i++)

{

free(hc[i].codestr);

}

return0;

}

longfrequency_data(FILE*in,longfrequency[])

{

inti,read_len;

unsignedcharbuf[256];

longfilesize;

for(i=0;i<256;i++)

frequency[i]=0;

fseek(in,0L,SEEK_SET);

read_len=256;

while(read_len==256)

{

read_len=fread(buf,1,256,in);

for(i=0;i

{

frequency[*(buf+i)]++;

}

}

for(i=0,filesize=0;i<256;i++)

{

filesize+=frequency[i];

}

returnfilesize;

}

intsearch_set(htnpht,intn,int*s1,int*s2)

inti,x;

longminValue=1000000,min=0;

for(x=0;x

{

if(ht[x].p==-1)break;

}

for(i=0;i

{

if(ht[i].p==-1&&ht[i].w

{

minValue=ht[i].w;

min=i;

}

}

*s1=min;

minValue=1000000,min=0;

for(i=0;i

if(ht[i].p==-1&&ht[i].w

=*s1)

minValue=ht[i].w;

min=i;

}

}

*s2=min;

return1;

}

intcreate_hftree(longw[],intn,htnodeht[])

{

intm,i,s1,s2;

if(n<1)return-1;

m=2*n-1;

if(ht==NULL)return-1;

for(i=0;i

{

ht[i].w=w[i];

ht[i].p=ht[i].l=ht[i].r=-1;

for(;i

{

ht[i].w=ht[i].p=ht[i].l=ht[i].r=-1;

}

for(i=n;i

{

search_set(ht,i,&s1,&s2);

ht[s1].p=ht[s2].p=i;

ht[i].l=s1;

ht[i].r=s2;

ht[i].w=ht[s1].w+ht[s2].w;

}

return0;

}

intencode_hftree(htnphtp,intn,hufcodehc[]){

inti,j,p,codelen;

*code=(unsigned

unsignedcharchar*)malloc(n*sizeof(unsignedchar));

if(code==NULL)return-1;

for(i=0;i

{

for(p=i,codelen=0;p!

=2*n-2;p=htp[p].p,codelen++){

code[codelen]=(htp[htp[p].p].l==p?

0:

1);

}

char

if((hc[i].codestr=(unsigned

*)malloc((codelen)*sizeof(unsignedchar)))==NULL)

{

return-1;

}

hc[i].len=codelen;

for(j=0;j

{

hc[i].codestr[j]=code[codelen-j-1];

}

}

free(code);

return0;unsignedcharchars_to_bits(constunsignedcharchars[8]){

inti;

unsignedcharbits=0;bits|=chars[0];

for(i=1;i<8;++i){

bits<<=1;bits|=chars[i];

}

returnbits;

}

intwrite_compress_file(FILE*in,FILE*out,htnpht,hufcodehc[],char*source_filename,longsource_filesize)

{

unsignedinti,read_counter,write_counter,zip_head=0xFFFFFFFF;

unsignedchar

write_char_counter,code_char_counter,copy_char_counter,

read_buf[256],write_buf[256],write_chars[8],filename_size=strlen(source_filename);

hufcode*cur_hufcode;

fseek(in,0L,SEEK_SET);

fseek(out,0L,SEEK_SET);fwrite(&zip_head,sizeof(unsignedint),1,out);fwrite(&filename_size,sizeof(unsignedchar),1,out);fwrite(source_filename,sizeof(char),filename_size,out);fwrite(&source_filesize,sizeof(long),1,out);

for(i=256;i<256*2-1;i++)

{

fwrite(&(ht[i].l),sizeof(ht[i].l),1,out);fwrite(&(ht[i].r),sizeof(ht[i].r),1,out);

}

write_counter=write_char_counter=0;

read_counter=256;

while(read_counter==256)

{read_counter=fread(read_buf,1,256,in);for(i=0;i

cur_hufcode=&hc[read_buf[i]];

code_char_counter=0;

while(code_char_counter!

=cur_hufcode->len)

{

copy_char_counter=(8-write_char_counter>

cur_hufcode->len-code_char_counter?

cur_hufcode->len-code_char_counter:

8-write_char_counter);

memcpy(write_chars+write_char_counter,cur_hufcode->codestr+code_c

har_counter,copy_char_counter);

write_char_counter+=copy_char_counter;

code_char_counter+=copy_char_counter;if(write_char_counter==8)

{

write_char_counter=0;

write_buf[write_counter++]=chars_to_bits(write_chars);

if(write_counter==256)

{

fwrite(write_buf,1,256,out);

write_counter=0;

}

}

}

fwrite(write_buf,1,write_counter,out);

if(write_char_counter!

=0)

{

write_char_counter=chars_to_bits(write_chars);fwrite(&write_char_counter,1,1,out);

}

return0;

}

voidget_mini_huffmantree(FILE*in,shortmini_ht[][2])

{

inti;

for(i=0;i<256;i++)

{

mini_ht[i][0]=mini_ht[i][1]=-1;

fread(mini_ht[i],sizeof(short),2*(256-1),in);

intwrite_decompress_file(FILE*in,FILE*out,shortmini_ht[][2],longbits_pos,longobj_filesize)

{

longcur_size;

unsignedcharread_buf[256],write_buf[256],convert_bit;unsignedintread_counter,write_counter,cur_pos;

fseek(in,bits_pos,SEEK_SET);

fseek(out,0L,SEEK_SET);read_counter=256-1;cur_size=write_counter=0;cur_pos=256*2-2;

while(cur_size!

=obj_filesize)

{

if(++read_counter==256)

{

fread(read_buf,1,256,in);read_counter=0;

for(convert_bit=128;convert_bit!

=0;convert_bit>>=1)

{

cur_pos=((read_buf[read_counter]&convert_bit)==0?

mini_ht[cur_pos][0]:

mini_ht[cur_pos][1]);

if(cur_pos<256)

{

write_buf[write_counter]=(unsigned

char)cur_pos;

if(++write_counter==256)

{

fwrite(write_buf,1,256,out);

write_counter=0;

}

cur_pos=256*2-2;

if(++cur_size==obj_filesize)

{

break;

}

fwrite(write_buf,1,write_counter,out);

return0;

}

intdecompress(char*source_filename,char*obj_filename)

{

int

error_code;

FILE

*in,*out;

short

mini_ht[256*2-1][2];

long

obj_filesize;

error_code=d_initial_files(source_filename,&in,obj_filename,&out);

if(error_code!

=0)

{

puts(”打开文件失败!

请重新输入文件路径:

");

returnerror_code;

}

fread(&obj_filesize,sizeof(long),1,in);

printf("解压文件大小:

%ld字节\n",obj_filesize);

get_mini_huffmantree(in,mini_ht);

error_code=write_decompress_file(in,out,mini_ht,ftell(in),obj_filesize);

if(error_code!

=0)

{

puts(”解压缩失败!

”);

returne

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 文学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1