算法报告三 哈夫曼编码
16122020 钟顺源
一、题目大意
给定n个数的出现频率,问几个数的哈夫曼编码是多少?
在构造Huffman树的过程中有些要求:
1.左儿子标记为0,右儿子标记为1;
2.左儿子的权值>=右儿子的权值;
3.相同权值w的两个字母x、y,出现时间晚的优先级高。
二、分析
那这其实就是贪心+模拟。
用什么模拟? 优先队列,也就是堆。
何为模拟?每次弹出堆中最小的两个值,合并成一个权值为两最小权值之和的新节点,并维护左右孩子,并插入堆中。
可以得知,插入堆的节点需要有这么几个参数:时间戳,频次,左孩子,右孩子。
struct node{
int id;
int lid,rid;
int val;
bool operator<(const node&q)const{
if(val==q.val) return id<q.id;
return val>q.val;
}
}a[1<<13];
那么为了构造唯一Huffman树,需要重载比较运算符:若频次一致,则插入时间晚的点优先级高,否则频次低的点优先级高。
构造出Huffman树后,再从根节点往下递归,左枝加‘0’,右枝加‘1’,遇到树叶,记忆化并返回。
最后按1~n的时间戳输出叶子节点与其编码即可。
三、代码
#include<bits/stdc++.h>
using namespace std;
#define clr(a, x) memset(a, x, sizeof(a))
#define mp(x, y) make_pair(x, y)
#define pb(x) push_back(x)
#define X first
#define Y second
#define fastin \
ios_base::sync_with_stdio(0); \
ci