# include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10, M = 5000, MAX = 1e9;
struct Node{
char c;
int idx, w, l = -1, r = -1;// 当前节点的下标,权重总和,及左右孩子下标
bool operator < (const Node& other) const {// 重定义小于号,以实现小根堆
return w >= other.w;
}
};
int n;
Node node[N]; int idx = 0; // 用静态数组存储各节点,idx表示节点下标
priority_queue<Node> pq;
string code[N];
void dfs(int i, string s){
// 从哈夫曼树上到下搜索,左分支标0,右分支标1
Node T = node[i];
if (T.idx < n){// 索引小于n,说明是字母所在的叶子节点,存储其编码
code[i] = s;
return;
}
dfs(T.l, s+'0');
dfs(T.r, s+'1');
}
void solve(){
while (pq.size() >= 2){// 每次选择两个最小的节点,将其合并并放入堆中
Node node1 = pq.top(); pq.pop();
Node node2 = pq.top(); pq.pop();
idx++;
Node nd = {' ', idx, node1.w + node2.w, node1.idx, node2.idx};
node[idx] = nd;
pq.push(node[idx++]);
}
dfs(pq.top().idx, "");
for (int i = 0; i < n; ++i) { // 打印编码结果
cout << node[i].c << " : " << code[i] << endl;
}
}
int main(){
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> node[idx].c >> node[idx].w;
node[idx].idx = idx;
pq.push(node[idx++]);
}
solve();
return 0;
}
哈夫曼编码的简单写法
于 2024-09-16 21:59:29 首次发布