二十二、计算WPL

二十二、计算WPL

文章目录

  • 二十二、计算WPL
    • 题目描述
    • 解题思路
    • 上机代码

题目描述

Huffman编码是通信系统中常用的一种不等长编码,它的特点是:能够使编码之后的电文长度最短。

输入:
第一行为要编码的符号数量n
第二行~第n+1行为每个符号出现的频率

输出:
对应哈夫曼树的带权路径长度WPL

测试输入 期待的输出 时间限制 内存限制 额外进程
测试用例 1 5
7
5
2
4
9
WPL=60 1秒 64M 0
测试用例 2 5
2
4
2
3
3
WPL=32 1秒 64M 0

解题思路

哈夫曼树的带权路径长度WPL,按道理来讲应该规规矩矩地建立哈夫曼树,逐层计算数值再求和。

当然,我们也有更好的思路,抛开哈夫曼树,只要抓住了其中的数学本质,借助队列一样可以算出 WPL 。


对于输入的序列,然后按照从小到大顺序加入队列中。

每次取出队列中的前两个小值,将两个值的和加到 sum 中,再将求和后的新值再次加入队列中,继续从队列中选取两个最小的值,n 个值一共选 n-1 次。这样,我们就模拟出了哈夫曼树的计算过程,每次取两个最小的值,将求和后的新值继续与其他值做比较再选取。

因为每次要取出的是两个最小的值,这其中涉及到了一个排序的问题,普通的队列只能按照加入的顺序进行读取,是无法实现排序的,因此我们使用优先队列来进行值的选取(优先队列自带了排序功能,方便好用)。每次需要的是最小值,所以我们对输入序列的元素取负值,这样可以保证队列中的最大值就是原序列中的最小值。

在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出 (first in, largest out)的行为特征。对于普通的数值来说,数值越大,优先级越高。

上机代码

#include
#include
#include
#include
using namespace std;
priority_queue<int>q;
int main()
{
	int n, i, x, sum = 0, t;
	cin >> n;
	for (i = 0; i<n; i++)
	{
		cin >> x;
		q.push(-x);//存入负值
	}
    //一共选n-1次
	for (i = 1; i<n; i++)
	{
		t = q.top();
		sum -= q.top();
		q.pop();
		t += q.top();
		sum -= q.top();
		q.pop();
		q.push(t);
	}
	cout <<"WPL="<< sum << endl;
	//system("pause");
	return 0;
}

你可能感兴趣的:(#,数据结构,数据结构,优先队列,WPL)