Programming Huffman coding, and provide the test example
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
#define MAXN 50
#define MAXT 100
//结果返回一棵完全二叉树,里面包含其中的编码方式
//输入N,接下来输入N个数,代表出现次数,然后输出每个叶子节点的编码
struct Node{
int num,w;//num表示这个节点在Tree数组中的下标
int f,lc,rc;//f=father,lc=left_child,rc=right_child
bool operator <(const Node b)const{
return w>b.w;
} //优先队列的比较方式
}Tree[MAXT+5];
char Ans[MAXN+5];
int N,size,Root;
priority_queue<Node> Q;
void unite(Node x,Node y){//将x和y结点合并到一起 这个函数太重要了
Tree[x.num].f=Tree[y.num].f=++size;//记住 size是一个全局变量 合成的新节点重新加入加入这个队列
Tree[size].lc=x.num;
Tree[size].rc=y.num;
Tree[size].num=size;
Tree[size].w=Tree[x.num].w+Tree[y.num].w;
Q.push(Tree[size]);//放入队列
}
void print(int u,int Len)//Len记录长度 其实真正的难点在于寻找这个编码方式
{
if(!Tree[u].lc&&!Tree[u].rc){
cout<<Tree[u].w<<":";
puts(Ans+1);
return;
}
Len++;
Ans[Len]='0';
print(Tree[u].lc,Len);
Ans[Len]='1';
print(Tree[u].rc,Len);
Ans[Len]=0;
}
int main(){
int n;//n个数字
cin>>n;
for(int i=1;i<=n;i++){
cin>>Tree[i].w;
Tree[i].num=i;//num记录的是初始时的下标1~n
Q.push(Tree[i]);//优先队列 实际上已经更改了优先级 权值越小 优先级别越高
}
if(n==1)
cout<<0<<endl;//特殊情况判断
size=n;//初始时size记录结点的序号
for(int i=1;i<n;i++){//从1~n进行循环遍历 可以认为出队列
Node u1=Q.top();
Q.pop();
Node u2=Q.top();
Q.pop();
unite(u1,u2);//这一步很重要 需要将pop出去的两个数合在一起 然后放到优先队列里面
}
for(int i=1;i<=size;i++){//find root
if(!Tree[i].f)
Root=i;
}
print(Root,0);
return 0;
}
//6
//45 13 12 16 9 5