实习报告6哈夫曼编码.docx
《实习报告6哈夫曼编码.docx》由会员分享,可在线阅读,更多相关《实习报告6哈夫曼编码.docx(16页珍藏版)》请在冰豆网上搜索。
![实习报告6哈夫曼编码.docx](https://file1.bdocx.com/fileroot1/2022-10/10/bad55a92-7944-4abe-8113-efea64f3825d/bad55a92-7944-4abe-8113-efea64f3825d1.gif)
实习报告6哈夫曼编码
1.初始化:
从文件humanWeight.txt(程序运行时,由用户输入)读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,将它存于文件hufTree.txt中。
2.编码:
利用已建好的哈夫曼树(如不在存,则从文件hufTree.txt中读入)对文件tobebin.txt字符集中的每一个进行编码,将结果放在codefile.txt中。
3.译码:
利用已建好的哈夫曼树将codefile.txt中的代码进行译码,结果保存在textfile.txt中。
4.印代码文件。
将文件codefile.txt以紧凑的格式显示在终端上,每行50个代码。
同时将结果保存在codeprint.txt中。
二.概要设计:
1.哈夫曼树的抽象数据类型定义:
ADThaffman
{数据对象:
D={ai|ai为charnode型的结点,i=1,2,3,……n,n>0}
数据关系:
R={|ai是D上的元素}
}ADThaffman
2.编码集结构体的抽象数据类型的定义:
ADTcode
{数据对象:
D1={ai|ai是charlink型的结点,i=1,2,……n,n>0}
D2={bi|bi是codelink型的结点,i=1,2,……n,n>0}
数据关系:
R1={|ai是D1上的元素}
R2={|bi是D2上的元素}
}ADTcode
3.程序分为四个部分:
1)读入字符集以及相应频度,建立哈夫曼树。
2)根据哈夫曼树得到每一个字符的哈夫曼编码。
3)读入要编码的字符串,根据哈夫曼树和编码集求出字符串的哈夫曼编码。
4)根据哈夫曼编码和哈夫曼树得到字符串。
三.详细设计:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////zy
//
//赫夫曼编/译码器
//朱勇13011090
//
///////////////////////////////////////////////////////////////////////////////////////////////////
#include
#include
#include
#include
usingnamespacestd;
///////////////////////////////////////////////////////////
//赫夫曼树和赫夫曼编码的存储表示
typedefstruct{
unsignedintweight;
unsignedintparent,lChild,rChild;
}HTNode,*HuffmanTree;//动态分配数组存储赫夫曼树
typedefstruct{
charch;
char*hufCh;
}HuffmanCode;//动态分配数组存储赫夫曼编码表
///////////////////////////////////////////////////////////
//权值字符结点类型
typedefstruct{
charch;
intwt;
}wElem;//动态分配数组存储读入字符与权值
///////////////////////////////////////////////////////////
//赫夫曼编码函数
voidHuffmanCoding(HuffmanTree&,
HuffmanCode*,
wElem*,
int);
///////////////////////////////////////////////////////////
//对文件tobebin.txt中的正文进行编码
//将结果存入codefile.txt
voidEnCoding(HuffmanCode*,constchar*);
///////////////////////////////////////////////////////////
//对文件codefile.txt里的代码进行译码
//将结果存入textfile.txt
voidDeCoding(HuffmanTree,
HuffmanCode*,
constchar*,
constint);
///////////////////////////////////////////////////////////
//对codefile.txt里的代码进行编排,显示,打印
voidPrintCode(constchar*,constchar*);
///////////////////////////////////////////////////////////
//选择两个最小的结点
voidSelectTwoNode(HuffmanTree,int,int&,int&);
intmain()
{
//
//用文件流对象hufInPut打开外部文件
//humanWeight.txt储存字符集大小n,以及n个字符和n个权值
ifstreamhufInPut("humanWeight.txt",ios:
:
in);
inthufNum=0;
hufInPut>>hufNum;//读入字符集大小n到hufNum
wElem*hufW=newwElem[hufNum];//分配n个字符和n个权值的储存空间
for(intii=0;ii{
//
//循环读入字符及其对应的权值
hufInPut>>hufW[ii].ch>>hufW[ii].wt;
}
hufInPut.close();//关闭humanWeight.txt文件
HuffmanTreehufT;//空树
HuffmanCode*hufC=(HuffmanCode*)malloc((hufNum+1)*sizeof(HuffmanCode));//分配n个字符编码的头指针向量
HuffmanCoding(hufT,hufC,hufW,hufNum);//编码中...
//
//用文件流对象hufTreeOutPut把赫夫曼树HT,HC输出到文件hufTree.txt中
ofstreamhufTreeOutPut("hufTree.txt",ios:
:
out);
hufTreeOutPut<<"--HT-------------------------------"<<<"weight"<<"parent"<<"lchild"<<"rchild"<for(inttOut=1;tOut<=2*hufNum-1;tOut++)
{
hufTreeOutPut<<<<<}
hufTreeOutPut<<"--endHT---------------------------"<<<"--HC-------------------------------"<for(intcOut=1;cOut<=hufNum;cOut++)
{
hufTreeOutPut<<""<>"<}
hufTreeOutPut<<"--convert--ok--------------------"<hufTreeOutPut.close();//输出完毕,关闭文件
delete[]hufW;//释放存
EnCoding(hufC,"tobebin.txt");//对正文编码
DeCoding(hufT,hufC,"codefile.txt",hufNum);//译码
PrintCode("codefile.txt","codeprint.txt");//打印代码
cout<return0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//
//w存放n个字符的权值(均大与0)
//构造赫夫曼树HT,并求出n个字符的赫夫曼编码HC
//
voidHuffmanCoding(HuffmanTree&HT,HuffmanCode*HC,wElem*w,intn)
{
if(n<=1)return;
intm=2*n-1;//赫夫曼树的结点数目
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//0号单元未用
HuffmanTreep=HT;
p++;//p指向HT的第1号单元
inti=0,ww=0;//ww为wElem*w的下标
for(i=1;i<=n;i++,p++,ww++)
{
p->weight=w[ww].wt;
p->parent=p->lChild=p->rChild=0;//
}//初始化
for(;i<=m;++i,++p)//
{
p->weight=p->parent=p->lChild=p->rChild=0;
}
//
//建赫夫曼树
//在HT[1..i-1]选择parent为0且weight最小的两个结点,其序号分别为s1和s2
//
ints1=0,s2=0;
for(i=n+1;i<=