Bootstrap

数据结构-哈夫曼树

#include <bits/stdc++.h>
#include <unordered_map>

using namespace std;

#define ll long long
// #define int ll
#define pii pair<int, int>
#define all(x) x.begin(), x.end()
#define endl '\n'
#define fer(i, m, n) for (int i = m; i < n; ++i)

const int MOD = 1e9 + 7;
const int N = 2e5 + 2;

struct HuffNode
{
    int w;
    HuffNode *left;
    HuffNode *right;
    HuffNode(int w) : w(w), left(nullptr), right(nullptr) {}
};

// 实现升序
struct cmp
{
    bool operator()(HuffNode *a, HuffNode *b)
    {
        return a->w > b->w;
    }
};

HuffNode *BuildTree(vector<int> w)
{
    if (w.empty())
        return nullptr;

    // 把每个节点放入优先队列中
    priority_queue<HuffNode *, vector<HuffNode *>, cmp> pq;
    fer(i, 0, w.size())
    {
        HuffNode *node = new HuffNode(w[i]);
        pq.push(node);
    }

    // while(!pq.empty()){
    //     cout << pq.top()->w << ' ';
    //     pq.pop();
    // }

    // 选取权值最小的两个子树进行合并,直到合并成一棵树
    while (pq.size() > 1)
    {
        HuffNode *left = pq.top();
        pq.pop();
        HuffNode *right = pq.top();
        pq.pop();
        HuffNode *par = new HuffNode(left->w + right->w);
        par->left = left, par->right = right;

        pq.push(par);
    }

    return pq.top();
}

// 进行编码
void encode(HuffNode *&T, unordered_map<int, string> &codes, string code)
{
    if (!T)
        return;
    // 判断是否为叶子结点
    if (!T->left && !T->right)
        codes[T->w] = code;
    else
    {
        encode(T->left, codes, code + "0");
        encode(T->right, codes, code + "1");
    }
}

// 对二进制串进行解码
string decode(HuffNode *root, string code)
{
    string ans = "";
    HuffNode *cur = root;
    for (char c : code)
    {
        if (c == '0')
            cur = cur->left;
        else
            cur = cur->right;

        if (!cur->left && !cur->right)
        {
            ans += to_string(cur->w) + ' ';
            cur = root;
        }
    }
    return ans;
}

void preorder(HuffNode *T)
{
    if (!T)
        cout << -1 << ' ';
    else
    {
        cout << T->w << ' ';
        if (T->left)
            preorder(T->left);
        else
            cout << -1 << ' ';
        if (T->right)
            preorder(T->right);
        else
            cout << -1 << ' ';
    }
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;
    vector<int> weight(n);
    fer(i, 0, n) cin >> weight[i];
    HuffNode *root = BuildTree(weight);
    // preorder(root);
    unordered_map<int, string> codes;
    encode(root, codes, "");
    for (auto it : codes)
        cout << it.first << ' ' << it.second << endl;
    string code;
    cin >> code;
    cout << decode(root, code) << endl;
    return 0;
}
;