#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;
}
哈夫曼树
最新推荐文章于 2025-01-02 21:11:47 发布