先用优先队列每次取出两个小的数字,然后变成一个数字,加入队列。建树采用数组实现。
#include <bits/stdc++.h>
#define Pair pair<int,string>
using namespace std;
struct node
{
int data;
double a;
int left;
int right;
}tree[1005];
map<string, int>mp;
auto cmp = [](int q, int w) {
if (tree[q].a != tree[w].a)
return tree[q].a > tree[w].a;
return tree[q].data < tree[w].data;
};
int n, cnt = 1;
priority_queue<int, vector<int>, decltype(cmp) >q(cmp);
void Init()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%d%lf", &tree[cnt].data, &tree[cnt].a);
q.push(cnt++);
}
}
void Build()
{
while (q.size() != 1)
{
node rot;
rot.left = q.top();
q.pop();
rot.right = q.top();
q.pop();
rot.a = tree[rot.left].a + tree[rot.right].a;
rot.data = ' ';
tree[cnt] = rot;
q.push(cnt++);
}
}
void BFS(int rot)
{
//BFS
queue<int>qq;
qq.push(rot);
while (!qq.empty())
{
int temp = qq.front();
qq.pop();
if (tree[temp].left == 0 && tree[temp].right == 0)
printf("%d ", tree[temp].data);
if (tree[temp].left != 0)
qq.push(tree[temp].left);
if (tree[temp].right != 0)
qq.push(tree[temp].right);
}
}
void Code(int rot)
{
//BFS
cout << endl << "哈夫曼编码为:" << endl;
queue<Pair>qq;
qq.push(Pair{ rot,"" });
while (!qq.empty())
{
Pair temp = qq.front();
qq.pop();
if (tree[temp.first].left == 0 && tree[temp.first].right == 0)
{
printf("%d : ", tree[temp.first].data);
cout << temp.second << endl;
mp[temp.second] = tree[temp.first].data;
}
if (tree[temp.first].left != 0)
qq.push(Pair{ tree[temp.first].left ,temp.second + '0' });
if (tree[temp.first].right != 0)
qq.push(Pair{ tree[temp.first].right,temp.second + '1' });
}
cout << endl;
}
void Decode()
{
cout << "输入一个编码:" << endl;
string s, t;
cin >> s;
int len = s.size();
for (int i = 0; i < len; i++)
{
t += s[i];
if (mp[t] != 0)
{
printf("%d", mp[t]);
t.clear();
}
}
}
int main()
{
Init();
Build();
int rot = q.top();
q.pop();
//BFS(rot);
Code(rot);
Decode();
}
/*
8
4 25
8 5
5 4
3 20
2 10
6 4
7 2
1 30
11010001001110011010110001111
*/