赫夫曼编码实验报告附源代码.docx
- 文档编号:9467623
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:21
- 大小:48.52KB
赫夫曼编码实验报告附源代码.docx
《赫夫曼编码实验报告附源代码.docx》由会员分享,可在线阅读,更多相关《赫夫曼编码实验报告附源代码.docx(21页珍藏版)》请在冰豆网上搜索。
赫夫曼编码实验报告附源代码
赫夫曼编码实验报告附源代码
四川大学计算机学院
学生实验报告
实验名称:
:
Huffman编码(二叉树应用)
指导教师:
xxx
姓名:
xxx
学号:
0000000
班级:
2009级5班
日期:
2010年11月
班级:
xxx姓名:
xxx学号:
00000000
一、实验三:
Huffman编码(二叉树应用)
二、实验的目的和要求:
1.要求对文件进行Huffman编码的算法,以及对乙编码文件进行解码的算法,为简单起见,可以假设文件是存放在一个字符向量;2.熟练掌握二叉树的应用;
3.熟练掌握计算机系统的基本操作方法,了解如何编辑、编译、链接和运行一个C++程序及二叉树上的基本运算;
4.上机调试程序,掌握查错、排错使程序能正确运行。
三、实验的环境:
指硬件和软件环境
1.硬件环境:
内存1016M,处理器:
Intel(R)Core(TM)2DuoCPU.,主频:
2.20GHZ
2.软件环环境:
操作系统:
WindowsXPMicrosoftvisualC++6.0
四、算法描述:
可用特殊符号加自然语言或算法框图(程序流程图、PAD图等)或伪语言(likeC++)。
:
开始
选择功能:
1.压缩2.解压3退出
Infp=fopen(inf
Y1.压缩输入要压缩文件Name,”rb”)Cin.answer==1Throwerror
==Null
fget(cinfp)==NullYThrowerror
目标文件指针指向文件开始处rewind(outfp)
输入目标文件
Fwrite()并初始化bits、chN
建立字符缓存器structBufferType
使源文件指针指向开始处rewind(infp)初始字符数组ch[]和字符频度w[]
取出字符cha=fgetc(infp)只想源文件指针开始处
rewind(infp)!
feof(infp)
Y
取出源文件字符cha=fgetc(infp)字符编码StringstrTmp=pMyHuffmanTree-
>Encode(cha)
!
feof(infp)N
Y
强行写入文件字符频度w[]++,文件大小size++WriteToOutfp()N
关闭文件fclose(infp),fclose(outfp)
处理结束释放空间,生成Huffman树
2.解压文件Cin.answer==2输入要解压文件
Infp=fopen(infYThrowerrorName,”rb”)
==Null取出字符cha=fgetc(infp)
!
feof(infp)Yfget(cinfp)==NullThrowerror
Y
N将cha转换二进制形式的
串StringstrTmp=””输入目标文件N
使源文件指针指向开始处For(i=0;I 读取大小fread()Len=size 释放空间,生成Huffman树Y 退出break 处理结束,关闭文件 fclose(fp),fclose(outfp) Cin.answer! =1&&cin.answr! =2break 五、源程序清单: 主文件名: Huffman.cpp #include"Utility.h" #include"Lk_stack.h" #include"Huffman.h" voidmain() { HuffmanTreehf; charc=0; charanswer; while(c! ='3') { cout< cout< cout< cout< "; cin>>c; switch(c) { case'1': hf.Code();break; case'2': hf.UnCode();break; } } } 文件名: Huffman.h constunsignedintn=256;//字符数 constunsignedintm=256*2-1;//结点总数 structHTNode{//压缩用Huffman树结点 unsignedlongweight;//字符频度(权值) unsignedintparent,lchild,rchild;}; structBuffer{//字节缓冲压缩用Huffman树 charch;//字节 unsignedintbits;//实际比特数}; classHuffmanTree{//Huffman树 public: voidCode();//编码 voidUnCode();//译码 private: HTNodeHT[m+1];//树结点表(HT[1]到HT[m]) charLeaf[n+1];//叶结点对应字符(leaf[1]到leaf[n]) char*HuffmanCode[n+1];//叶结点对应编码(*HuffmanCode[1]到*HuffmanCode[n]) unsignedintcount;//频度大于零的字符数 unsignedintchar_index[n];//字符对应在树结点表的下标(char_index[0]到char_index[n-1]) unsignedlongsize;//被压缩文件长度 FILE*infp,*outfp;//输入/出文件 Bufferbuf;//字符缓冲 voidStat();//统计字符出现频度并过滤掉频度为零的字符 //在HT[0]~HT[k]中选择parent为-1,树值最小的两个结点s1,s2 voidSelect(unsignedintk,unsignedint&s1,unsignedint&s2); voidWrite(unsignedintbit);//向outfp中写入一个比特 voidWrite(unsignedintnum,unsignedintk);//向outfp中写入k个比特 voidWriteToOutfp();//强行写入outfp voidRead(unsignedint&bit);//从infp中读出一个比特 voidRead(unsignedint&num,unsignedintk);//从infp中读出k个比特 intNToBits(unsignedintnum);//0~num之间的整数用二进位表示所需的最少位数 voidCreateFromCodeFile();//由编码文件中存储的树结构建立Huffman树 //由被压缩文件建立Huffman树,将树结构存入编码文件的文件头部中,并求每个字符的Huffman编码 voidCreateFromSourceFile();}; voidHuffmanTree: : Code()//编码 { charinfName[256],outfName[256]; cout<<"Pleaseinputsourcefilename(sizelessthan4GB): ";//被压缩文件最多4GB cin>>infName; if((infp=fopen(infName,"rb"))==NULL){ cout<<"Cannotopenfile: "< exit (1); } if(feof(infp)! =0){ cout<<"Emptysourcefile: "< exit (1); } cout<<"Pleaseinputcodefilename: "; cin>>outfName; if((outfp=fopen(outfName,"wb"))==NULL){ cout<<"Cannotopenfile: "< exit (1); } cout<<"Pocessing..."< unsignedcharch; unsignedinti,c; for(i=0;i<=n;i++)HuffmanCode[i]=NULL; CreateFromSourceFile(); rewind(infp); ch=fgetc(infp); while(feof(infp)==0){ c=char_index[ch]; for(i=0;i if(HuffmanCode[c][i]=='0')Write(0); elseWrite (1); } ch=fgetc(infp); } WriteToOutfp(); fclose(infp);fclose(outfp); cout<<"Processend."< voidHuffmanTree: : UnCode() { charinfName[256],outfName[256]; cout<<"Pleaseinputcodefilename: "; cin>>infName; if((infp=fopen(infName,"rb"))==NULL){ cout<<"Cannotopenfile: "< exit (1); } if(feof(infp)! =0){ cout<<"Emptycodefile: "< exit (1); } cout<<"Pleaseinputtargetfilename: "; cin>>outfName; if((outfp=fopen(outfName,"wb"))==NULL){ cout<<"Cannotopenfile: "< exit (1); } cout<<"Pocessing..."< unsignedintbit,c,i; CreateFromCodeFile();//建立Huffman树 Read(bit); for(i=0;i c=2*count-1;//2*count-1为根结点的下标 while((HT[c].lchild! =0||HT[c].rchild! =0)&&(feof(infp)==0)){ if(bit==0)c=HT[c].lchild; elsec=HT[c].rchild; Read(bit); } fputc(Leaf[c],outfp);//将字符写入outfp中 } fclose(infp);fclose(outfp); cout<<"Processend."< voidHuffmanTree: : Stat()//统计字符出现频度并过滤掉频度为零的字符{ unsignedinti,cha; for(i=1;i<=n;i++)HT[i].weight=0; size=0; rewind(infp); cha=fgetc(infp); while(feof(infp)==0)//统计字符出现频度 { HT[cha+1].weight++; size++; cha=fgetc(infp); } count=0; for(cha=0;cha if(HT[cha+1].weight>0){ count++; Leaf[count]=cha; HT[count].weight=HT[cha+1].weight; char_index[cha]=count; } } } voidHuffmanTree: : Select(unsignedintk,unsignedint&s1,unsignedint&s2) {//s1,s2为权值最小的根,且s1的权值小于s2的权值 unsignedintroot_count=0;//根结点数; unsignedintroot_index[n];//根结点下标; unsignedinttem,i,j; for(i=1;i<=k;i++) if(HT[i].parent==0) root_index[root_count++]=i; s1=root_index[0];s2=root_index[1]; if(HT[s1].weight>HT[s2].weight){ tem=s1;s1=s2;s2=tem; } for(i=2;i j=root_index[i]; if(HT[j].weight s2=j; if(HT[s1].weight>HT[s2].weight){ tem=s1;s1=s2;s2=tem; } } } } voidHuffmanTree: : Write(unsignedintbit)//向outfp中写入一个比特 { buf.bits++; buf.ch=(buf.ch<<1)+bit; if(buf.bits==8){//缓冲区已满,写入outfp fputc(buf.ch,outfp); buf.bits=0; buf.ch=0; } } voidHuffmanTree: : Write(unsignedintnum,unsignedintk)//向outfp中写入k个比特 { Stack unsignedinti,bit; for(i=1;i<=k;i++){ s.push(num&1); num=(num>>1); } for(i=1;i<=k;i++){ s.top(bit); Write(bit); s.pop(); } } voidHuffmanTree: : WriteToOutfp()//强行写入outfp{ unsignedintl=buf.bits; if(l>0) for(unsignedinti=0;i<8-l;i++)Write(0); } voidHuffmanTree: : Read(unsignedint&bit)//从infp中读出一个比特 { if(buf.bits==0){ buf.ch=fgetc(infp); buf.bits=8; } bit=(buf.ch&128)>>7; buf.ch=buf.ch<<1; buf.bits--; } voidHuffmanTree: : Read(unsignedint&num,unsignedintk)//从infp中读出k个比特 { unsignedintbit; num=0; for(unsignedinti=0;i Read(bit); num=(num<<1)+bit; } } intHuffmanTree: : NToBits(unsignedintnum)//0~num之间的整数用二进位表示所需的位数{ unsignedintl=0,power=1; while(power<=num){ l++;power=power*2; } returnl; } voidHuffmanTree: : CreateFromCodeFile()//由编码文件中存储的树结构建立Huffman树{ buf.bits=0;//清空缓冲区 buf.ch=0; unsignedintnum,l,i; rewind(infp); fread(&size,sizeof(unsignedlong),1,infp); Read(count,8); count=count+1; for(i=1;i<=count;i++) fread(&Leaf[i],sizeof(char),1,infp); l=NToBits(2*count-1); for(i=1;i<=count;i++){ HT[i].lchild=0; HT[i].rchild=0; } for(i=count+1;i<=2*count-1;i++){ HT[i].lchild=(Read(num,l),num); HT[i].rchild=(Read(num,l),num); } } voidHuffmanTree: : CreateFromSourceFile()//由被压缩文件建立Huffman树,将树结构存入编码文件的文件头部中,并求每个字符的Huffman编码 { Stat();//统计字符出现频度并过滤掉频度为零的字符 //由被压缩文件建立Huffman树 unsignedinti,s1,s2; for(i=1;i<=count;i++)HT[i].parent=HT[i].lchild=HT[i].rchild=0; for(i=count+1;i<=2*count-1;i++){//建立Huffman树 Select(i-1,s1,s2);//选择parent为0,权值最小的两个结点s1,s2 HT[s1].parent=HT[s2].parent=i; HT[i].parent=0;HT[i].lchild=s1;HT[i].rchild=s2; HT[i].weight=HT[s1].weight+HT[s2].weight; } //将树结构存入编码文件的文件头部中 unsignedintl; buf.bits=0;//清空缓冲区 buf.ch=0; rewind(outfp); fwrite(&size,sizeof(unsignedint),1,outfp); Write(count-1,8); for(i=1;i<=count;i++) fwrite(&Leaf[i],sizeof(char),1,outfp); l=NToBits(2*count-1); for(i=count+1;i<=2*count-1;i++){ Write(HT[i].lchild,l); Write(HT[i].rchild,l); } //求每个字符的Huffman编码 unsignedintstart,c,f; char*cd;//编码临时变量 for(i=1;i<=n;i++) if(HuffmanCode[i]! =NULL){ delete[]HuffmanCode[i];//释放存储空间 HuffmanCode[i]=NULL; } cd=newchar[count];//分配求编码的工作空间 cd[count-1]='\0';//编码结束符 for(i=1;i<=count;i++){//逐位求Huffman编码 start=count-1;//编码结束符位置 for(c=i,f=HT[i].parent;f! =0;c=f,f=HT[c].parent)//从叶到根求编码 if(HT[f].lchild==c)cd[--start]='0'; elsecd[--start]='1'; HuffmanCode[i]=newchar[count-start];//为第i个字符编码分配空间 strcpy(HuffmanCode[i],&cd[start]);//从cd复制编码到HuffmanCode } delete[]cd; } 文件名: LK_stack.h template structNode{ Node_entryentry;//数据成员 Node Node();//构造 Node(Node_entryitem,Node }; template classStack{ public: //标准栈声明方法 Stack(); boolempty()const; Error_codepush(constStack_entry&item); Error_codepop(); Error_codetop(Stack_entry&item)const; voidclear(); ~Stack(); Stack(constStack voidoperator=(constStack protected: Node template Node : Node() { next=NULL; } template Node : Node(Node_entryitem,Node { entry=item; next=add_on; } template Stack : Stack() { top_node=NULL; } template boolStack : empty()const{ if(top_node==NULL) returntrue; else returnfalse; } template Error_codeStack : push(constStack_entry&item) { Node
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 赫夫曼 编码 实验 报告 源代码
![提示](https://static.bdocx.com/images/bang_tan.gif)