标题
huffman编码
时间限制
2 S
内存限制
10000 Kb
问题描述
假设用于通信的电文由n(4<n<30)个字符组成,字符在电文中出现的频度(权值)为w1w2…wn,试根据该权值序列构造哈夫曼树,并计算该树的带权路径长度。
问题输入
一组数据,第1行为n的值,第2行为n个整数,表示字符的出现频度。 问题输出 输出一个整数,表示所构造哈夫曼树的带权路径长度。
输入样例
8
7 19 2 6 32 3 21 10
输出样例
261
写在前面
好久不见呀,这一年都没更新博客,可能上学期学java没什么动力更,我也不知道我在干神魔【doge】。最近刷期末数据结构题目遇到了这么个问题,求哈夫曼树的带权路径长度,学过的人都知道老老实实创建一棵哈夫曼树有多难,大概一伯行代码了吧,我这么懒是不可能自己写的嘿嘿 。于是我就想有没有什么偷懒的办法,因为之前在系统的学习C++的标准库函数,想着能不能用到这上面的。这一搜,嘿,还真搜到了,要是期末出这题,嘿嘿,别人一百行的代码(他们还不一定写的出来)我二十行就搞定了,那不是很爽啊哈哈。
我是参考的这两篇博客:
哈夫曼树 — 优先队列(C++STL)
哈夫曼树以及哈夫曼编码的构造步骤
从这上面学到了很多。大家没事都可以多看看别人写的博客。
主要思路
其实知道了有优先队列这么个东西就很简单了。我们都知道队列是先进先出,但优先队列讲究一个优先级,它会根据数据的优先级来决定先输出哪一个后输出哪一个。当然这个优先级是可以自己定义的。我们只需要根据权值,选择两个最小值求和,再压入队列,再取两个最小值求和,再压入队列,重复下去直到队列只剩一个元素。
代码
#include <bits/stdc++.h>
using namespace std;
int main(){
priority_queue< int,vector<int>,greater<int> > p; //int类型数据,
//底层实现是vector数组
//greater<int>表示升序排列
int n,value,max1,max2,sum=0,path=0;
cin >> n;
for(int i=0;i<n;i++){ //输入数,压队列
cin >> value;
p.push(value);
}
while(p.size()>1){ //还剩一个元素时
max1=p.top(); //取最小的两个值就和,并弹出
p.pop();
max2=p.top();
p.pop();
sum=max1+max2;
p.push(sum); //和 压队列
path+=sum; //权值
}
cout << path << endl;
return 0;
}
是不是很简单,快学起来。
这是我学习STL的博客:
STL教程:C++ STL快速入门(非常详细)
写的真的很好很详细,也可以去看网课说的也很详细。