本来想着练一下哈夫曼编码那一大串代码的,然后发现,找不到题目,这个可能要等到以后涉及到大工程时才能真正实践到吧。然后找到了SDUT的两题哈夫曼题,加深了对哈夫曼树和优先队列的理解。
开始不知道这个公式(最优二叉树的权=每个叶子节点的权值之和=除根节点外的节点的权值之和=哈夫曼编码的长度),一直没想明白为什么要求除根节点外的节点的权值之和.
最后一个等于哈夫曼编码长度可以通过以下例子得出:a b c,建树:
3
2 1
1 1
易知哈夫曼编码的长度=1*2+1*2+1*1=5=最优二叉树的权
然后一个字符对应8位ascii编码。
sdut 3345
#include<cstdio>
#include<queue>
#include<cstring>
#include<string>
#include<iostream>
#include<map>
#include<set>
using namespace std;
string s;
int node,wpl,n,mm,as;
int main(){
while(cin>>s){
node=wpl=0;
map<char,int>m;
priority_queue<int,vector<int>,greater<int> >q;///优先队列默认元素大的优先级高,要让数据小的优先级高这么处理。
for(int i=0;i<s.length();i++){
m[s[i]]++;
}
for(int i=0;i<s.length();i++){
if(m[s[i]]){
q.push(m[s[i]]);
m[s[i]]=0;
}
}
while(!q.empty()){
n=q.top();
q.pop();
if(!q.empty()){
mm=q.top();
q.pop();
node=n+mm;
wpl+=node;
q.push(node);
}
}
as=s.length()*8;
double ans=(as*1.0)/wpl;
printf("%d %d %.1f\n",as,wpl,ans);
}
return 0;
}
/***************************************************
User name: Rocky
Result: Accepted
Take time: 0ms
Take Memory: 196KB
Submit time: 2017-11-27 23:08:45
****************************************************/
sdut 2127
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn=1e4+5;
int n,a[maxn],nn,mm,wpl,node;
int main(){
while(scanf("%d",&n)!=EOF){
wpl=0;
priority_queue<int,vector<int>,greater<int> >q;
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
for(int i=0;i<n;i++){
q.push(a[i]);
}
while(!q.empty()){
nn=q.top();
q.pop();
if(!q.empty()){
mm=q.top();
q.pop();
node=nn+mm;
wpl+=node;
q.push(node);
}
}
printf("%d\n",wpl);
}
return 0;
}
/***************************************************
User name: Rocky
Result: Accepted
Take time: 4ms
Take Memory: 312KB
Submit time: 2017-11-27 23:40:45
****************************************************/