哈夫曼文件压缩实验报告.docx
- 文档编号:7773940
- 上传时间:2023-01-26
- 格式:DOCX
- 页数:14
- 大小:221.21KB
哈夫曼文件压缩实验报告.docx
《哈夫曼文件压缩实验报告.docx》由会员分享,可在线阅读,更多相关《哈夫曼文件压缩实验报告.docx(14页珍藏版)》请在冰豆网上搜索。
哈夫曼文件压缩实验报告
数据结构实验报告三——哈夫曼文件压缩
实验题目:
哈夫曼文件压缩
实验目标:
输入一个有10k单词得英文文档。
输出压缩后得二进制文件,并计算压缩比。
数据结构:
栈与哈夫曼树。
1.定义栈()
typedefstruct{
ﻩchar*elem;
ﻩintstacksize;
int top;}STACK;
2.定义哈夫曼树()
typedefstruct{
int weight;
ﻩintleft,right;
intparent;}HTNode;
需要得操作有:
1、初始化栈(Initstack)
voidInitstack(STACK*s){
ﻩs->elem=(char*)malloc(sizeof(int)*1000);
s->stacksize=1000;
ﻩs->top=-1;
}
2、压栈(push)
voidpush(STACK*s,int e){
ﻩs->elem[++s->top]=e;
}
3、弹栈(pop)
voidpop(STACK *s,int*e){
ﻩif(s->top!
=-1)
ﻩ*e=s->elem[s->top--];
}
4、构造哈夫曼树(Inithuffman)
voidInithuffman(intwset[n],intk,HuffTree HT[]){//构造哈夫曼树
inti,m;
ints1,s2;
m=k*2-1;
for(i=0;i HT[i]=(HuffTree)malloc(sizeof(HTNode)); ﻩHT[i]->weight=(i wset[i]: 0); ﻩHT[i]->parent=-1; ﻩﻩHT[i]->left=HT[i]->right=-1; } ﻩfor(i=k;i ﻩﻩselect(HT,k,i,&s1,&s2); //在HT[1、、、i-1]中选择parent为0且weight为最小得两个结点,其下标分别为s1与s2 ﻩﻩHT[i]->left=s1; ﻩﻩHT[i]->right=s2; ﻩHT[i]->weight=HT[s1]->weight+HT[s2]->weight; ﻩHT[s1]->parent=HT[s2]->parent=i; } } 其中用到另一个基本操作: 找到哈夫曼树中最小与次小得结点(select) 5、找到哈夫曼树中最小与次小得结点(select) void select(HuffTreeHT[255],inta,inti,int*p,int *q){ intj=0,k=0,*HT1,temp; HT1=(int *)malloc(sizeof(int)*(i-1));//存放权值 ﻩfor(j=0;j ﻩﻩif(HT[j]->parent==-1){ ﻩHT1[k]=HT[j]->weight; //把没有parent得结点得权值放在HT1中 ﻩk++; ﻩ} //ﻩprintf("%4d%4d%4d%4d%4d\n",HT[j]->parent,HT[j]->left,HT[j]->right,HT[j]->weight,HT1[k-1]); } j=0; ﻩwhile(j<2) { //找到权值最小与第二小得结点 ﻩfor(k=j;k<(i-(i-a)*2);k++){ ﻩﻩif(HT1[j]>HT1[k]){ temp=HT1[k]; ﻩﻩﻩHT1[k]=HT1[j]; ﻩHT1[j]=temp; ﻩﻩ} } ﻩﻩj++; } ﻩk=0; ﻩfor(j=0;j if(HT[j]->parent==-1) ﻩﻩif(HT[j]->weight==HT1[0]&&k<1){ //将最小得权值赋到*p中 ﻩﻩ*p=j; ﻩﻩﻩk++; ﻩﻩ} ﻩj++; ﻩ} ﻩfor(j=0;j<i;){ ﻩﻩif(HT[j]->parent==-1) ﻩif(j! =*p) ﻩif(HT[j]->weight==HT1[1]&&k<2){ //将第二小得权值赋到*q中 ﻩﻩﻩﻩ*q=j; ﻩk++; ﻩ} j++; //ﻩprintf("%4d%4d%4d%4d\n",HT[i]->parent,HT[i]->left,HT[i]->right,HT[i]->weight); ﻩ} } 6、根据哈夫曼树得到各字符对应得哈夫曼编码(Huffman) voidHuffman(HuffTreeHT[2*n-1],int k,charstr[][20]){ int i,j,e,t1=0,t2=0; charc; ﻩSTACKst; ﻩfor(i=0;i<k;i++){ ﻩﻩif(HT[i]->right==-1&&HT[i]->left==-1){ //找一个叶子结点 ﻩﻩInitstack(&st); ﻩﻩHT[i]->right=HT[i]->left==-2; j=i; //记录其下标 ﻩﻩwhile(HT[j]->parent! =-1){ if(HT[HT[j]->parent]->right==j) //找到一个叶子结点,如果她就是其parent结点得右结点,就将此边记为1 ﻩpush(&st,'1'); ﻩﻩﻩelse ﻩﻩﻩpush(&st,'0'); //在左边记为0 ﻩﻩﻩﻩj=HT[j]->parent; //循环操作直到到达根结点 ﻩ} ﻩﻩﻩc=i; ﻩﻩprintf("\t%c",c); //打印此字符 ﻩﻩfor(;st、top! =-1;){ ﻩﻩﻩﻩpop(&st,&e); ﻩﻩprintf("%c",e); //打印其二进制编码 ﻩstr[t1][t2]=e; //将二进制编码存放在str中 ﻩt2++; ﻩﻩ} ﻩﻩﻩputchar('\n'); ﻩﻩstr[t1][t2]='\0'; ﻩﻩt2=0; ﻩﻩt1++; ﻩﻩ} } } 算法设计: 1、从文件中逐个读取字符,记录其出现次数以及文件总字符数,由此确定其频率高低。 2、根据字符频率创建哈夫曼树,然后求出哈夫曼编码。 3、将哈夫曼编码输出到另一个文件中,并统计字数,求出压缩率。 源程序 #include #include<malloc、h> #include<process、h> #define n 127 typedefstruct{ ﻩint weight; ﻩintleft,right; ﻩintparent;}HTNode;//哈夫曼数组结构类型 typedefHTNode*HuffTree; typedefstruct{ ﻩchar*elem; ﻩintstacksize; ﻩinttop;}STACK;//栈得结构类型 voidInitstack(STACK *s){ ﻩs->elem=(char*)malloc(sizeof(int)*1000); s->stacksize=1000; ﻩs->top=-1; }//初始化栈 voidpush(STACK*s,inte){ s->elem[++s->top]=e; }//压栈 voidpop(STACK *s,int*e){ if(s->top! =-1) *e=s->elem[s->top--]; }//弹栈 voidselect(HuffTreeHT[255],int a,inti,int*p,int*q){//找到哈夫曼树中权值最小与次小得结点并返回指针 intj=0,k=0,*HT1,temp; HT1=(int*)malloc(sizeof(int)*(i-1)); //存放权值 for(j=0;j<i;j++){ if(HT[j]->parent==-1){ ﻩﻩHT1[k]=HT[j]->weight; //把没有parent得结点得权值放在HT1中 k++; ﻩ} //ﻩprintf("%4d%4d%4d%4d%4d\n",HT[j]->parent,HT[j]->left,HT[j]->right,HT[j]->weight,HT1[k-1]); } ﻩj=0; while(j<2){ //找到权值最小与第二小得结点 for(k=j;k<(i-(i-a)*2);k++){ ﻩﻩif(HT1[j]>HT1[k]){ temp=HT1[k]; ﻩﻩHT1[k]=HT1[j]; ﻩﻩHT1[j]=temp; } ﻩ} ﻩj++; ﻩ} k=0; for(j=0;j if(HT[j]->parent==-1) ﻩif(HT[j]->weight==HT1[0]&&k<1){ //将最小得权值赋到*p中 ﻩ*p=j; ﻩk++; ﻩ} ﻩﻩj++;ﻩ ﻩ} for(j=0;j ﻩﻩif(HT[j]->parent==-1) ﻩif(j! =*p) ﻩif(HT[j]->weight==HT1[1]&&k<2){ //将第二小得权值赋到*q中 ﻩﻩ*q=j; ﻩﻩk++; ﻩ} ﻩﻩj++; //ﻩprintf("%4d%4d%4d%4d\n",HT[i]->parent,HT[i]->left,HT[i]->right,HT[i]->weight); } } voidInithuffman(intwset[n],intk,HuffTreeHT[]){ //构造哈夫曼树 ﻩinti,m; ﻩint s1,s2; ﻩm=k*2-1; ﻩfor(i=0;i<m;i++){ //初始化HT数组 ﻩﻩHT[i]=(HuffTree)malloc(sizeof(HTNode)); ﻩﻩHT[i]->weight=(i<k? wset[i]: 0); ﻩHT[i]->parent=-1; ﻩHT[i]->left=HT[i]->right=-1; } for(i=k;i<m;i++){ //主循环,完成n-1次合并 select(HT,k,i,&s1,&s2); //在HT[1、、、i-1]中选择parent为0且weight为最小得两个结点,其下标分别为s1与s2 ﻩHT[i]->left=s1; ﻩHT[i]->right=s2; ﻩHT[i]->weight=HT[s1]->weight+HT[s2]->weight; ﻩﻩHT[s1]->parent=HT[s2]->parent=i; } } voidHuffman(HuffTreeHT[2*n-1],intk,charstr[][20]){//根据哈夫曼树得到各字符对应得哈夫曼编码 ﻩint i,j,e,t1=0,t2=0; ﻩcharc; ﻩSTACK st; ﻩfor(i=0;i<k;i++){ if(HT[i]->right==-1&&HT[i]->left==-1){ //找一个叶子结点 ﻩﻩﻩInitstack(&st); ﻩHT[i]->right=HT[i]->left==-2; ﻩj=i; //记录其下标 ﻩﻩﻩwhile(HT[j]->parent! =-1){ ﻩﻩﻩif(HT[HT[j]->parent]->right==j) //找到一个叶子结点,如果她就是其parent结点得右结点,就将此边记为1 ﻩﻩﻩpush(&st,'1'); ﻩﻩﻩelse ﻩﻩpush(&st,'0'); //在左边记为0 ﻩﻩj=HT[j]->parent; //循环操作直到到达根结点 } c=i; printf("\t%c",c); //打印此字符 ﻩfor(;st、top! =-1;){ ﻩpop(&st,&e); ﻩﻩﻩprintf("%c",e); //打印其二进制编码 str[t1][t2]=e; //将二进制编码存放在str中 ﻩﻩt2++; ﻩ} ﻩﻩputchar('\n'); ﻩstr[t1][t2]='\0'; ﻩt2=0; t1++; ﻩ} ﻩ} } void main(){ FILE*fp1,*fp2; HuffTreeHT[2*n-1]; inti=0,sum1=0,sum2=0; ﻩfloat press; ﻩcharstr[n][20]; charelem,ch; intcount[n]={0}; if((fp1=fopen("text1、txt","r"))==NULL){ ﻩprintf("can'topenthefile! \n"); ﻩexit(0); ﻩ} while(! feof(fp1)){ //读取文件中字符 ﻩﻩelem=fgetc(fp1); ﻩi=elem; count[i]++; //记录字符频率 } Inithuffman(count,n,HT); ﻩ//for(i=0;i<253;i++) //printf("%4d%4d%4d%4d\n",HT[i]->parent,HT[i]->left,HT[i]->right,HT[i]->weight); ﻩHuffman(HT,2*n-1,str); //对文章进行哈夫曼编码 if((fp1=fopen("text1、txt","r"))==NULL){ ﻩprintf("can'topenthefile! \n"); ﻩexit(0); } if((fp2=fopen("text2、txt","w"))==NULL){ ﻩﻩprintf("can't openthe file! \n"); ﻩexit(0); } while(! feof(fp1)){ ﻩch=fgetc(fp1); //读取text1中字符 ﻩﻩi=ch; ﻩfputs(str[i],fp2); //将此字符得二进制编码输出到text2中 sum1++; ﻩ} if((fp2=fopen("text2、txt","r"))==NULL){ printf("can'topenthefile! \n"); exit(0); ﻩ} ﻩwhile(! feof(fp2)){ ﻩch=fgetc(fp2); ﻩsum2++; } press=(float)sum2/(float)(sum1*8); //压缩率 ﻩprintf("\n\n原字节数: %d\n现字节数: %d\n压缩率: %、6f\n",8*sum1,sum2,press); } 截图 输入: (自动认定为text1、txt,其中有17,278w)文件 输出结果: 1、哈夫曼树(检验建树成功) 2、所求参数: 原字节数: 789656,现字节数: 475137,压缩率: 0、601701 实验总结与心得 程序较长,调试中遇到较多困难;之前写得程序,过几天就会觉得理解不就是很顺畅,需要加适当注释。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 哈夫曼 文件 压缩 实验 报告