- 1. 哈夫曼编码
【问题描述】读入n个字符所对应的权值,自底向上构造一棵哈夫曼树,自顶向下生成每一个字符对应的哈夫曼编码,并依次输出。另,求解某字符串的哈夫曼编码,求解某01序列的译码。
【输入形式】输入的第一行包含一个正整数n,表示共有n个字符需要编码。其中n不超过100。第二行中有n个用空格隔开的正整数,分别表示n个字符的权值,依次按照abcd...的默认顺序给出。然后是某字符串和某01序列。
【输出形式】前n行,每行一个字符串,表示对应字符的哈夫曼编码。然后是某字符串的哈夫曼编码,某01序列的译码。
【注意】保证每次左子树比右子树的权值小;如出现相同权值的,则先出现的在左子树,即下标小的在左子树。
【样例输入】
8
5 29 7 8 14 23 3 11
aabchg
00011110111111001
【样例输出】
0001
10
1110
1111
110
01
0000
001
000100011011100010000
acdef
#include <bits/stdc++.h>
using namespace std;
typedef struct node
{
int weight;
int parent, lc, rc;
int flag;
} huff;
void select(node v[], int n, int &s1, int &s2)
{
int min = -1;
for (int i = 0; i < n; i++)
{
if (v[i].parent == 0)
{
min = i;
break;
}
}
for (int i = min + 1; i < n; i++)
{
if (v[i].weight < v[min].weight && v[i].parent == 0)
{
min = i;
}
}
s1 = min;
for (int i = 0; i < n; i++)
{
if (v[i].parent == 0 && i != s1)
{
min = i;
break;
}
}
for (int i = min + 1; i < n; i++)
{
if (v[i].weight < v[min].weight && v[i].parent == 0 && i != s1)
{
min = i;
}
}
s2 = min;
}
void build_huff(int n, huff v[], int len)
{
int s1, s2;
for (int i = n; i < len; i++)
{
select(v, i, s1, s2);
// cout << s1 << " " << s2 << endl;
v[s1].parent = i;
v[s2].parent = i;
v[i].lc = s1;
v[i].rc = s2;
v[i].weight = v[s1].weight + v[s2].weight;
}
}
void fun1(huff v[], int n, char c[], int i) //第一个功能,即求哈夫曼编码
{
stack<char> s;
int j = v[i].parent;
while (j)
{
if (v[j].lc == i)
s.push('0');
else if (v[j].rc == i)
s.push('1');
i = j;
j = v[j].parent;
}
int k = 0;
while (!s.empty())
{
c[k++] = s.top();
s.pop();
}
c[k] = '\0';
}
void fun2(int n, huff v[], string s) //根据编码求原字母;
{
n = (n - 1) * 2;
int i = 0;
while (i < s.size())
{
int cur = n;
while (v[cur].flag)
{
if (s[i] == '0')
{
cur = v[cur].lc;
}
else if (s[i] == '1')
{
cur = v[cur].rc;
}
i++;
// cout << v[v[cur].rc].flag << v[v[cur].lc].flag << endl;
}
char a = 'a' + cur;
cout << a;
}
}
int main()
{
int n;
cin >> n;
huff v[200];
for (int i = 0; i < n; i++)
{
cin >> v[i].weight;
v[i].parent = v[i].lc = v[i].rc = 0;
v[i].flag = 0;
}
for (int i = n; i < 2 * n - 1; i++)
{
v[i].parent = v[i].lc = v[i].rc = 0;
v[i].flag = 1;
}
build_huff(n, v, 2 * n - 1);
cout << endl;
string s1;
string s2;
cin >> s1 >> s2;
char c[60];
for (int i = 0; i < n; i++) //一个一个的求其编码
{
fun1(v, n, c, i);
cout << c << endl;
}
cout << endl;
for (int i = 0; i < s1.size(); i++) //一个一个的求其编码
{
int j = s1[i] - 'a';
fun1(v, n, c, j);
cout << c;
}
cout << endl;
fun2(n, v, s2);
}