/*huffman测试:
如:
char c[]={'a','b','c','d','e','f'}; 字符集
int a[] ={ 16, 4, 8, 6, 20, 3}; 频度集
huffman树
57
0/ /1
21 36
0/ /1 0/ /1
(c:8) 13 (a:16) (e:20)
0/ /1
(d:6) 7
0/ /1
(f:3) (b:4)
编码:
a: 10
b: 0111
c: 00
d: 010
e: 11
f: 0110
测试数据:
10
101
10010
101100
110100110
a
error
aec
ad
edf
*/
#include<iostream>
#include<string>
#include<queue>
using namespace std;
struct hufnode
{
hufnode(char c,int f):ch(c),fre(f),left(NULL),right(NULL){};
hufnode(char c,int f,hufnode *l,hufnode *r):ch(c),fre(f),left(l),right(r){};
hufnode(const hufnode& node):ch(node.ch),fre(node.fre),left(node.left),right(node.right){};
char ch;
int fre;
hufnode *left;
hufnode *right;
friend bool operator < (hufnode a,hufnode b) //优先队列按递减排序
{
return a.fre > b.fre;
}
};
/*
功能:构造huffman树
入口参数:字符集c[],对应频度集a[],字符集总数
出口参数:huffman的根节点
*/
hufnode* make_huf_tree(char *c,int *a,int n)
{
priority_queue<hufnode> temp;
for(int i = 0;i<n;i++)
{
hufnode x = hufnode(c[i],a[i]);
temp.push(x);
}
while(temp.size()>1) //构造的时候很神奇,完全不是按手工的方案,但是找不到错误。
{
hufnode* left = new hufnode(temp.top());
temp.pop();
hufnode* right = new hufnode(temp.top());
temp.pop();
hufnode* top = new hufnode('0',left->fre + right->fre,left,right);
temp.push(*top);
}
return new hufnode(temp.top());
}
//遍历huffman树解码
string traversal(hufnode* root,string str)
{
string temp = ""; //解码结果
int n = str.size();
hufnode *point = root;
bool error = false;
for(int i = 0;i<n;)
{
while(point->left != NULL) //每个节点要么都有左右子树,要么都没有,因此判断一个分支即可。
{
if(i>=n)
{
error = true;
temp = "error";
break;
}
else
(str[i++]=='0')?(point = point->left):(point = point->right);
}
if(!error)
{
temp += point->ch;
point = root;
}
else
break;
}
return temp;
}
int main()
{
char c[]={'a','b','c','d','e','f'};
int a[]={16,4,8,6,20,3};
hufnode* root = make_huf_tree(c,a,6);
string str;
while(cin>>str)
cout<<traversal(root,str)<<endl;
}