数据结构学习之哈夫曼树和哈夫曼编码
数据结构学习之哈夫曼树和哈夫曼编码
0x1 前言
终于完成作业了,有点小开心,虽然翘了一上午的课。
0x2 题目
0x2.1 题目要求
假设用于通信的电文仅由8个字母组成,字母在电文中出现的频率分别为7,19,2,6,32,3,21,10。试为这8个字母设计哈夫曼编码。
0x2.2 题目输入
/*
8
a 0.07
b 0.19
c 0.02
d 0.06
e 0.32
f 0.03
g 0.21
h 0.10
*/
0x2.3 代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#define MAXV 100+7
using namespace std;
typedef struct
{
char data;
int rchild;
int lchild;
int parent;
double weight;
}HTNode;
typedef struct
{
char cd[MAXV];
int start;
}HTCode;
typedef struct
{
char plain;
double rate;
}HTPlain;
void CreateHT(HTNode ht[],int n0)
{
int i,j;
double min1,min2;
int rnode,lnode;
// init 2n0-1个结点
for(i=0;i<2*n0-1;i++)
ht[i].parent=ht[i].rchild=ht[i].lchild=-1;
for(j=n0;j<2*n0-1;j++)
{
min1=min2=32767;
rnode=lnode=-1;
int k;
for(k=0;k<=j-1;k++)
{
if(ht[k].parent==-1)
{
//cout<<ht[k].weight<<endl;
if(ht[k].weight<min1)
{
min2=min1;
//如果有比最小还要小的话那么当前最小给rnode
rnode=lnode;
min1=ht[k].weight;
lnode=k;
} else if(ht[k].weight<min2)
{
min2=ht[k].weight;
rnode=k;
}
}
}
//cout<< ht[lnode].data<< " " <<ht[rnode].data<<endl;
ht[j].weight=ht[lnode].weight + ht[rnode].weight;
ht[j].lchild=lnode;
ht[j].rchild=rnode;
ht[lnode].parent=j;
ht[rnode].parent=j;
}
}
void CreateHcode(HTNode ht[],HTCode hcd[],int n0)
{
HTCode hc;
int f,c;
for(int i=0;i<n0;i++)
{
hc.start=n0;
c=i;
f=ht[i].parent;
//cout<< f <<endl;
while(f!=-1)
{
if(ht[f].lchild == c)
{
hc.cd[hc.start--]='0';
//cout<<hc.cd[hc.start+1];
}
if(ht[f].rchild == c)
hc.cd[hc.start--]='1';
c=f;
f=ht[f].parent;
}
hc.start++;
hcd[i]=hc;
}
}
void ShowHTCode(HTNode ht[],HTCode hcd[],int n0)
{
for(int i=0;i<n0;i++)
{
cout<< ht[i].data<<":";
for(int j=hcd[i].start;j<=n0;j++)
{
cout<<hcd[i].cd[j];
}
cout<<"\t";
}
}
void ShowWPL(HTNode ht[],HTCode hcd[],int n0)
{
double wpl=0;
for(int i=0;i<n0;i++)
{
wpl+=(n0-hcd[i].start+1)*ht[i].weight;
}
cout<< wpl <<endl;
}
int main()
{
int n;
HTPlain Plain[MAXV];
HTNode ht[MAXV];
HTCode hcd[MAXV];
cout<< "please input the number of char(need to be HTCode):"<<endl;
cin>>n;
cout<< "input the char and rate" <<endl;
for(int i=0;i<n;i++)
{
cin>>ht[i].data>>ht[i].weight;
//cout<< Plain[i].plain << Plain[i].rate <<endl;
}
CreateHT(ht,n);
CreateHcode(ht,hcd,n);
cout<< "Huffman tree:" <<endl;
ShowHTCode(ht,hcd,n);
cout<<endl;
cout<< "Weight Path Length:"<<endl;
ShowWPL(ht,hcd,n);
return 0;
}