一、实验要求与目的
1、熟悉贪心算法的基本原理与适用范围。
2、使用贪心算法编程给出哈夫曼编码。
二、实验内容
编程实现哈夫曼编码,并给出测试实例
三、实现思想
运用优先队列的数据结构, 我们在考虑k元Huffman编码时,最大费用肯定是二叉的情况,因为深度越大,被加的次数会越多,另外,优先队列中数值大的优先级越高;但是最小费用和就是k叉了,与二叉不同的时,我们可以这样考虑,如果最后一次不足k叉,那么肯定不是最优解,那么我们只能通过补0的方式让最后一次又添加(k-1)个新的元素,即可实现。
四、实现代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define mmax 999
int stone[mmax];
int max_stone(int n,int k){
priority_queue<int > q;
//生成最大优先队列
for(int i=0;i<n;i++)
q.push(stone[i]);
int sum=0;
int max=0;
//求解最大的石子分流数目 分流次数越多越好
while(q.size()>2){
sum=0;
for(int i=0;i<2;i++)
{
sum+=q.top();
q.pop();
}
max+=sum;
q.push(sum);
}
while(!q.empty()){
max+=q.top();
q.pop();
}
return max;
}
int min_stone(int n,int k){
priority_queue<int ,vector<int>,greater<int> > q;
//生成最小优先队列
int m=(n-1)%(k-1);
n=n+(k-1-m)%(k-1);
//补充0
for(int i=0;i<n;i++)
q.push(stone[i]);
int sum=0;
int min=0;
//求解最小的石子分流数目 分流次数越少越好
while(q.size()>k){
sum=0;
for(int i=0;i<k;i++)
{
sum+=q.top();
q.pop();
}
min+=sum;
q.push(sum);
}
while(!q.empty()){
min+=q.top();
q.pop();
}
return min;
}
int main()
{
int n,k;
cin>>n>>k;
for(int i=0;i<n;i++)
cin>>stone[i];
cout<<max_stone(n,k)<<" "<<min_stone(n,k)<<endl;
return 0;
}
//7 3
//45 13 12 16 9 5 22