算法分析与设计实践-作业11-哈夫曼编码

哈夫曼编码

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)

5.源码

https://github.com/lu-225/As-before/blob/master/2018212212124%20%E9%99%86%E5%AE%B6%E8%BE%89%20%E5%AE%9E%E9%AA%8C11/%E5%93%88%E5%A4%AB%E6%9B%BC%E7%BC%96%E7%A0%81.cpp

猜你喜欢

转载自blog.csdn.net/qq_43633353/article/details/106202529