哈夫曼树

博客围绕哈夫曼树展开,虽无具体内容,但哈夫曼树是信息技术领域重要概念,在数据压缩等方面有应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 #include <queue>
#include <cstring>
#include <algorithm>
#include <vector>
#include <utility>
#include <string>
#include <iostream>
using namespace std;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>> > q;
struct hftr
{
    int val, parent, l, r;
    char cc;
    string hfcode="";
    int len=0;
    void create(hftr tr[], char ch[], int w[], int n)
    {
        for (int i = 0; i < 2 * n - 1; i++)
        {
            tr[i].parent = tr[i].l = tr[i].r = -1;
        }
        for (int i = 0; i < n; i++)
        {
            tr[i].val = w[i];
            tr[i].cc = ch[i];
            q.push(make_pair(tr[i].val, i));
        }
        int i1, i2;
        for (int i = n; i < 2 * n - 1; i++)
        {
            if (!q.empty())
            {
                i1 = q.top().second;
                q.pop();
            }
            if (!q.empty())
            {
                i2 = q.top().second;
                q.pop();
            }
            tr[i].val = tr[i1].val + tr[i2].val;
            tr[i].l = i1, tr[i].r = i2;
            tr[i1].parent = i;
            tr[i2].parent = i;
            q.push(make_pair(tr[i].val, i));
        }
    }
    void make_code(string hfcode[], hftr tr[], int n)
    {
        int cur = 0;
        int parent = 0;
        for (int i = 0; i < n; i++)
        {
            parent = tr[i].parent;
            cur = i;
            while (parent != -1)
            {
                tr[i].len++;
                if (tr[parent].l == cur)
                {
                    hfcode[i] += '0';
                    tr[i].hfcode+='0';
                }
                if (tr[parent].r == cur)
                {
                    hfcode[i] += '1';
                    tr[i].hfcode+='1';
                }
                cur = parent;
                parent = tr[parent].parent;
            }
            reverse(hfcode[i].begin(), hfcode[i].end());
            cout << tr[i].cc << " " << tr[i].val << " " << hfcode[i] << endl;
        }
    }
    void encode(hftr tr[]) //在建立好哈夫曼树的基础上,由输入的01字符串解码出对应码  选择哪个树解码
    {
        string s;
        cin>>s;
        int n=s.length();
        int root=0; //若已知树的节点,则树根在2*n-2处 从0编码
        while(tr[root].parent!=-1) root++;//不知树的节点数,寻找;
        int j=root;
        for(int i=0;i<n;i++)
        {
          if(s[i]=='0')
          {
              j=tr[j].l;
          }
          else if(s[i]=='1')
          {
              j=tr[j].r;
          }
          if(tr[j].l==-1&&tr[j].r==-1)
          {
             cout<<tr[j].cc<<" "<<tr[j].val<<endl;
             j=root;
          }
        }
    }
    int small_wpl(hftr tr[])
    {
       int parent=0;
       int cnt=0;
       int wpl=0;
      /* for(int i=0;;i++)
       {
           if(tr[i].l!=-1||tr[i].r!=-1) break;
           parent=tr[i].parent;
           cnt=0;
           while (parent!=-1)
           {
               cnt++;
               parent=tr[parent].parent;
           }
           wpl+=cnt*tr[i].val;
       } */
     //  cout<<wpl<<endl;
       for(int i=0;;i++)
       {
           if(tr[i].l!=-1||tr[i].r!=-1) break;
          // wpl+=tr[i].hfcode.length()*tr[i].val;
           wpl+=tr[i].len*tr[i].val;
       }
       return wpl;
    }
};
int main()
{
    int n;
    cin >> n;
    int *w = new int[n];
    char *ch = new char[n];
    for (int i = 0; i < n; i++)
    {
        cin >> ch[i];
        cin >> w[i];
    }
    hftr *tr = new hftr[n * 2 - 1];
    tr->create(tr, ch, w, n);
    string *hfcode = new string[n];
    tr->make_code(hfcode, tr, n);
    tr->encode(tr);
    cout<<(tr->small_wpl(tr))<<endl;
    return 0;
}