基本概念
给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
带权路径长度:
题目
哈夫曼编码
注意考虑树只有一个点的情况 ```cpp
include
include
include
include
include
include
using namespace std;
const int N = 1010;
char s[N];
unordered_map
int main() {
#ifdef SUBMITfreopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);long _begin_time = clock();#endifwhile (scanf("%s", s), strcmp(s, "END") != 0) {int len = strlen(s);rec.clear(); // 记得清空for (int i = 0; i < len; i++) {rec[s[i]]++;}priority_queue<int, vector<int>, greater<int>> heap; // 优先队列没有clear方法for (auto it = rec.begin(); it != rec.end(); it++) {heap.push(it->second);// cout << (double)it->second / len << ' ';}// cout << endl;int avg = 0;if (heap.size() == 1) { // 注意,只有一个点时,带权路径长度就是那个点的权值avg = heap.top();}while (heap.size() > 1) { // 至少有两个点才能合并double a1 = heap.top(); heap.pop();double a2 = heap.top(); heap.pop();avg += a1 + a2;heap.push(a1 + a2);}// cout << avg << endl;int ori = len * 8;printf("%d %d %.1lf\n", ori, avg, (double)ori / avg);}#ifdef SUBMITlong _end_time = clock();printf("\n\ntime = %ld ms", _end_time - _begin_time);#endifreturn 0;
} ```
