#include <stdlib.h>
#include <iostream>
int *findMin(struct TreeNode *trees,int length);
using namespace std;
struct huffmanCode{
int *p;
int start;
};
struct TreeNode{
int wight;
int parent;
int lchild;
int rchild;
};
class huffmanTree{
public :
struct TreeNode *array;
int start;
int length;
huffmanTree(int *array,int length);
void print(int start);
struct huffmanCode Code(int index);
};
huffmanTree::huffmanTree(int *array,int length){
//创建节点数组 初始化
// struct TreeNode trees[length*2-1];
struct TreeNode *trees;
trees=(struct TreeNode*)malloc((2*length-1)*sizeof(struct TreeNode));
int *p;//权重最小两个节点下标
for(int i=0;i<length*2-1;i++){
if(i<length){
trees[i].wight=array[i];
}
trees[i].lchild=-1;
trees[i].rchild=-1;
trees[i].parent=-1;
}
//创建huffmanTree
for(int i=0;i<length-1;i++){
p=findMin(trees,length+i);
trees[i+length].lchild=p[0];
trees[i+length].rchild=p[1];
trees[i+length].wight=trees[p[0]].wight+trees[p[1]].wight;
trees[p[0]].parent=i+length;
trees[p[1]].parent=i+length;
}
this->start=2*length-1; //数组长度
this->array=trees;
this->length=length;
}
//输出哈弗曼树 树根应该是在下标为2*length-2处
void huffmanTree::print(int start){
cout<<this->array[start].wight<<" ";
if(this->array[start].lchild!=-1){
this->print(this->array[start].lchild);
}
if(this->array[start].rchild!=-1){
this->print(this->array[start].rchild);
}
}
//输出编码 参数是下标
struct huffmanCode huffmanTree::Code(int index){
struct huffmanCode code;
struct TreeNode child=this->array[index];
int parent=child.parent;
code.start=this->length;
code.p=(int *)malloc(length*sizeof(int));
while(parent!=-1){
if(this->array[parent].lchild==index){
code.p[code.start]=0;
}else{
code.p[code.start]=1;
}
index=parent;
code.start--;
parent=this->array[parent].parent;
}
for(int i=code.start+1;i<=length;i++){
cout<<code.p[i];
}
return code;
}
int main(void){
int array[5]={1,2,3,3,4};
huffmanTree tree(array,5);
tree.print(tree.start-1);
tree.Code(1);
return 0;
}
//查找两个最小值下标
int *findMin(struct TreeNode *trees,int length){
int min,min2;
int x,x2;
int *p;
p=(int*)malloc(2*sizeof(int));
//初始化起始值
min=min2=10000;
x=x2=0;
//开始查找
for(int i=0;i<length;i++){
if(trees[i].parent==-1){
if(trees[i].wight<=min){
min2=min;
x2=x;
min=trees[i].wight;
x=i;
}else if(trees[i].wight<min2){
min2=trees[i].wight;
x2=i;
}
}
}
p[0]=x;
p[1]=x2;
return p;
}