题目描述
在本题中,我们将要讨论的是自顶向下的赫夫曼编码算法。从根出发,遍历整棵赫夫曼树从而求得各个叶子结点所表示的字符串。算法的关键部分可以表示如下:
在本题中,读入n个字符所对应的权值,生成赫夫曼编码,并依次输出计算出的每一个赫夫曼编码。
输入
输入的第一行包含一个正整数n,表示共有n个字符需要编码。其中n不超过100。
第二行中有n个用空格隔开的正整数,分别表示n个字符的权值。
输出
共n行,每行一个字符串,表示对应字符的赫夫曼编码。
样例输入
<span style="color:#333333">8
5 29 7 8 14 23 3 11
</span>
样例输出
<span style="color:#333333">0110
10
1110
1111
110
00
0111
010
</span>
提示
在本题中,与上一题不同的是在求赫夫曼编码的过程中,使用了从根出发开始遍历整棵赫夫曼树的自顶向下的算法。通过这两道题目的联系,应该能够熟练的掌握赫夫曼树和赫夫曼编码的构造和使用方法了。
#define MAX_SIZE 100005
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int arr[105], n;
struct HT
{
int weight;
int parent, lch, rch;
string code;
};
HT *huffTree;
string *hfCode;
string hashtable[MAX_SIZE];
void selectMinTwo(int high, int &s1, int &s2)
{
int min = INT32_MAX;
for (int i = 1; i <= high; i++)
{
if (huffTree[i].parent == 0 && min > huffTree[i].weight)
{
min = huffTree[i].weight;
s1 = i;
}
}
min = INT32_MAX;
for (int i = 1; i <= high; i++)
{
if (huffTree[i].parent == 0 && min > huffTree[i].weight && i != s1)
{
min = huffTree[i].weight;
s2 = i;
}
}
if (s1 > s2)
{
swap(s1, s2);
}
}
void HuffmanCoding()
{
int m, i;
if (n <= 1)
return;
m = 2 * n - 1;
huffTree = new HT[m + 1];
for (i = 1; i <= n; i++)
{
huffTree[i].weight = arr[i];
huffTree[i].lch = huffTree[i].rch = huffTree[i].parent = 0;
}
for (i = n + 1; i <= m; ++i)
{
huffTree[i].lch = huffTree[i].rch = huffTree[i].parent = 0;
}
for (i = n + 1; i <= m; i++)
{
int s1, s2;
selectMinTwo(i - 1, s1, s2);
huffTree[i].weight = huffTree[s1].weight + huffTree[s2].weight;
huffTree[i].lch = s1, huffTree[i].rch = s2;
huffTree[s1].parent = huffTree[s2].parent = i;
}
hfCode = new string[n + 1];
fill(hfCode,hfCode+n+1,"");
for (i = 1; i <= m; i++)
{
huffTree[i].weight = 0;
}
int index = m;
string codet = "";
while(index){
if(huffTree[index].weight == 0){
huffTree[index].weight = 1;
if(huffTree[index].lch!=0){
codet = codet + '0';
index = huffTree[index].lch;
}else {
hfCode[index] = codet;
}
}else if(huffTree[index].weight == 1){
huffTree[index].weight = 2;
if(huffTree[index].rch !=0){
codet = codet + '1';
index=huffTree[index].rch;
}
}else{
index = huffTree[index].parent;
codet = codet.substr(0,codet.length()-1);
//huffTree[index].weight = 0;
}
}
}
int main()
{
int i;
while (cin >> n)
{
for (i = 1; i <= n; i++)
{
cin >> arr[i];
}
HuffmanCoding();
for (i = 1; i <= n; i++)
{
cout << hfCode[i] << endl;
}
delete[] huffTree;
delete[] hfCode;
}
return 0;
}
/**************************************************************
Problem: 1761
User: morizunzhu
Language: C++
Result: 正确
Time:0 ms
Memory:5144 kb
****************************************************************/