哈夫曼编码的简单写法

# 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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值