哈夫曼编码
1.问题
代码(码字):Q{001,00,010,01}表示字符a,b,c,d
同一序列:0100001
产生两种译码(产生歧义):01 00 001;010 00 01
二元前缀码:任何字符的代码不能作为其他字符代码的前缀
利用二元前缀码译码:从第一个字符开始一次读入每个字符(0或1),如果发现独到的字串与某个码字相等,就将这个子串译作相应的码字:然后从下一个字符开始继续这个过程,直到读完输入的字符串为止。
二元前缀编码存储:二叉树结构,每个字符作为树叶,对应这个字符的前缀码看作根到这片树叶的一条路径,每个节点通向做儿子的边记作0,通向右儿子的边记作1。
问题:给定字符集C={x1,x2,…,xn}和每个字符的频率f(xi),求关于C的一个最优前缀码。
2.解析
构造最优前缀码的贪心算法就是哈夫曼算法(Huffman)
有a、b、c、d、e,f 6个字符,它们的权值分别为5,1,3,7,2,10
3.设计
priority_queue <int,vector<int>,greater<int> > q;
//升序队列,小顶堆
int main(){
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
q.push(x);
}
int ans=0;
n--;
while(n--){
int x=q.top();
q.pop();
int y=q.top();
q.pop();
int t=x+y;
ans+=t;
q.push(t);
}
printf("%d\n",ans);
}
4.分析
O(nlogn)频率排序:for循环O(n),插入操作O(logn)
算法时间复杂度是O(nlogn)