/*
* author : BoJing .Wang
* time : Ang 1st,2011
* goal : implement huffman code
*
*/
#include <iostream>
#include <cstring>
using namespace std;
static int Code[20] = {
12,34,35,42,14,57,51,31,42,98,
52,76,62,95,64,73,82,70,69,67
};
struct MinValue{
int frist; //最小值的下标
int second; //次值的下标
int x1;
int x2;
};
struct Huffman{
int value; //结点值
int flag; //标记(0/1)
int parent; //父结点的下标
int right; //右孩子的下标
int left; //左孩子的下标
};
struct EnCode{
int value; //结点值
int start; //编码开始位置
int bit[10]; //编码
};
void InitHuffman(Huffman Node[],int n){
for(int i = 0;i < 2*n-1;i ++){
if(i < n) Node[i].value = Code[i];
else Node[i].value = 0;
Node[i].flag = 0;
Node[i].parent = 0;
Node[i].left = -1;
Node[i].right = -1;
}
}
//选择两个最小值
MinValue selectMin(Huffman Node[],int n,int t){
MinValue mv = {100000,100000,0,0};
for(int i = 0;i < n+t;i ++){
if(Node[i].value < mv.frist && Node[i].flag == 0){
mv.second = mv.frist;
mv.x2 = mv.x1;
mv.frist = Node[i].value;
mv.x1 = i;
}else if(Node[i].value < mv.second && Node[i].flag == 0){
mv.second = Node[i].value;
mv.x2 = i;
}
}
return mv;
}
void CombineData(Huffman Node[],int n,int t,MinValue m){
Node[m.x1].parent = n+t;
Node[m.x2].parent = n+t;
Node[m.x1].flag = 1;
Node[m.x2].flag = 1;
Node[n+t].value = Node[m.x1].value + Node[m.x2].value;
Node[n+t].left = m.x1;
Node[n+t].right = m.x2;
return ;
}
void HuffmanCode(Huffman Node[],EnCode code[],int n){
EnCode c;
int child,parent;
memset(&c,0,sizeof(c));
for(int i = 0;i < n;i ++){
child = i;
parent = Node[child].parent;
c.value = Node[child].value;
c.start = n-11;
while(parent){
if(Node[parent].left == child)
c.bit[c.start] = 0;
else c.bit[c.start] = 1;
c.start --;
child = parent;
parent = Node[child].parent;
}
for(int j = c.start+1;j < n-10;j ++){
code[i].bit[j] = c.bit[j];
}
code[i].start = c.start;
code[i].value = c.value;
}
}
int main(){
MinValue m;
Huffman hufftree[40];
EnCode code[20];
InitHuffman(hufftree,20);
for(int i = 0;i < 19;i ++){
m = selectMin(hufftree,20,i);
CombineData(hufftree,20,i,m);
}
HuffmanCode(hufftree,code,20);
cout << "Huffman code as follow :" << endl;
for(int i = 0;i < 20;i ++){
cout << "value : "<<hufftree[i].value <<", code : ";
for(int j = code[i].start+1;j < 10;j ++)
cout << code[i].bit[j];
cout << endl;
}
return 0;
}