UVA240可变基哈夫曼编码

题解:本题为可变基哈夫曼编码,普通的哈夫曼编码为二叉树,即R=2.

例如:输入3 4 5 7 8 1 5,表示基数R3,字符个数N=4,每个字符的频率为A:5、B: 7、C:8、D:15构建的哈夫曼树

算法设计:

1、先补充虚拟字符,使N=k*(R-1)+R,k为整数,即(N-R) % (R-1) =0;

2、每个节点都包含frequency、va、id这3个域,分别表示频率、优先值、序号;

3、定义优先级。频率越小越优先,如果频率相等,则值越小越优先;

4、将所有节点都加入优先队列。

5、构建可变基哈夫曼树。

6、进行可变基哈夫曼树编码。

#include <bits/stdc++.h>
using namespace std;
struct node {
	int freq, va, id;
	node(int x = 0, int y = 0, int z = 0) {
		freq = x, va = y, id = z;
	}
	bool operator <(const node &b) const {
		if (freq == b.freq) {
			return va > b.va;
		}
		return freq > b.freq;
	}
};
const int maxn = 100;
int R, N; //基数、字母个数
int n, c; //补虚拟字母后的个数n,新生成字母编号c
int fre[maxn], father[maxn], code[maxn];
priority_queue<node>Q;
int main() {
	int cas = 1;
	while (cin >> R && R) {
		cin >> N;
		memset(fre, 0, sizeof(fre));
		int total = 0;
		for (int i = 0; i < N; i++) {
			cin >> fre[i];
			total += fre[i];
		}
		n = N;
		while ((n - R) % (R - 1) != 0) //补虚拟节点
			n++;
		while (!Q.empty()) //优先队列清空
			Q.pop();
		for (int i = 0; i < n; i++) //所有节点入队
			Q.push(node(fre[i], i, i));
		c = n; //新合成节点编号
		int rec = 0; //统计所有频率和值
		while (Q.size() != 1) { //剩余一个节点停止合并
			int sum = 0, minva = n;
			for (int i = 0; i < R; i++) {
				sum += Q.top().freq; //统计频率和
				minva = min(Q.top().va, minva); ///求最小优先值
				father[Q.top().id] = c; //纪录双亲
				code[Q.top().id] = i; //纪录编码
				Q.pop();//出队
			}
			Q.push(node(sum, minva, c));
			c++;
			rec += sum;
		}
		c--;
		printf("%d集合:平均长度 %0.2f\n", cas, 1.0 * rec / total);
		for (int i = 0; i < N; i++) {
			int cur = i;
			string s;
			while (cur != c) {
				s.push_back(code[cur] + '0');
				cur = father[cur];
			}
			reverse(s.begin(), s.end()); //翻转代码
			cout << " " << char('A' + i) << ":" << s << endl;
			cout << endl;
			cas++;
		}
	}
	return 0;
}

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值