哈夫曼编码
一、需求分析
从终端读入字符集大小n,依次输入n个字符和相应的权值,建立哈夫曼树。
输入一串电文,程序显示出电文翻译的比特流,在输入一串比特流,程序显示比特流翻译的电文。
二、部分代码
1.创建结构体
typedef struct{
char data;
int weight;
int parent;
int lchild;
int rchild;
}HTElemType;
typedef struct{
HTElemType HT[100]; //结构体
int nodes;
int root;
}HTree;
struct Sqstack{
char base[100];
int top;
};
2.创建哈夫曼树
void CreateHTree(HTree &htree,int n)
{
int s1,s2;
htree.nodes=2*n-1;
if(htree.nodes>1000)
return;
cout<<"输入"<<n<<"字符及其权值:"<<endl;
//构造森林
for(int i=0;i<n;i++) {
cin>>htree.HT[i].data>>htree.HT[i].weight;
htree.HT[i].parent=-1;
htree.HT[i].lchild=-1;
htree.HT[i].rchild=-1;
}
//构造哈夫曼树
for(int j=n;j<(2*n-1);j++)//两个权重合并增加的结点
{
Select(j,htree,s1);
htree.HT[s1].parent=j;
Select(j,htree,s2);
htree.HT[s2].parent=j;
htree.HT[j].weight=htree.HT[s1].weight+htree.HT[s2].weight;
htree.HT[j].lchild=s1;
htree.HT[j].rchild=s2;
htree.HT[j].parent=-1;
}
htree.root=htree.nodes-1; //
return; }
3.选择权重最小的哈夫曼树
void Select(int index,HTree htree,int &s1)
{
int min=1000;
for(int i=0;i<index;i++)
{
if(htree.HT[i].weight<min&&htree.HT[i].parent==-1)//找出最小的权重
{
min= htree.HT[i].weight;
s1=i;
} } }
代码说明:找出哈夫曼树中最小权重的字符,用s1传回CreateHTree(HTree &htree,int n)函数中。
4.为字符编码
void Coding(HTree htree,int i){
char e;
Sqstack s;
if(i<0||i>(htree.nodes+1)/2)
return;
s.top=0;
Push(s,'\0');
while(htree.HT[i].parent!=-1)//不是树根
{
int p= htree.HT[i].parent;
if(htree.HT[p].lchild==i)//左孩子是i时
Push(s,'0');
else Push(s,'1');
i=p;
}
while(s.top!=0)
{
Pop(s,e);
if(e!='0')
cout<<e;
}
}
代码说明:在主函数中,如果输入的字符与哈夫曼数上的字符相等,则把字符的序号传到编码中,序号为i,如果i=htree.HT[p].lchild,则把0入栈,否则1入栈,最后把栈中的值弹出来,则为字符的编码。
5.比特流翻译成电文
int DCoding (HTree htree,int &m,string str1)
{
while(str1[m]!='\0')
{
int n =htree.root;
while(htree.HT[n].lchild==-1||htree.HT[n].rchild==-1)
{
if(str1[m]=='0')//左
n=htree.HT[n].lchild;
else //右
n= htree.HT[n].rchild;
m++;
}
cout<<htree.HT[n].data;
}
return m;
}
代码说明:如果比特流为0,则找哈夫曼树的左孩子,为1找哈夫曼树的右孩子,直到最后一个结点为空指针,输出一个电文,若m不为0,循环上面的步骤。
6.进栈函数
bool Push(Sqstack &s,char e)//压栈函数
{
if(1000==s.top) return false;
s.base[s.top++]=e;
return 1;
}
7.出栈函数
bool Pop(Sqstack &s,char &e)//出栈函数
{
if(s.top==0) return false;
e=s.base[s.top-1];
s.top--;
return 1;
}
本程序借鉴资料与相关代码,不住之处希望指出。