哈夫曼树及其编码。
测试样例:
8
5 29 7 8 14 23 3 11
样例输出:
0110
10
1110
1111
110
00
0111
010
#include<bits/stdc++.h>
using namespace std;
typedef unsigned int uint;
const int MAXM = 200;
typedef struct {
uint weight;
uint parent, lchild, rchild;
}HTNode, * HuffmanTree;
typedef char** HuffmanCode;
int visit[MAXM];
void Select(HuffmanTree HT, int n, uint& s)
{
uint a = 10000, sa;
for (int i = 1; i <= n; i++) {
if (!visit[i] && HT[i].weight < a) {
a = HT[i].weight;
sa = i;
}
}
s = sa;
visit[sa] = 1;
}
void HuffmanCoding(HuffmanTree& HT, HuffmanCode& HC, uint* w, int n)
{
//w存放n个字符的权值(均大于0),构造哈夫曼树HT,并求出哈夫曼编码HC
if (n <= 1) return;
int m = 2 * n - 1;
uint s, s1, s2;
HT = (HuffmanTree)malloc(sizeof(HTNode) * (m + 1));
HuffmanTree p;
int i;
for (p = HT + 1, i = 1; i <= n; ++i, ++p, ++w)
{
*p = { *w, 0,0,0 };
}
for (; i <= m; ++i, ++p) {
*p = { 0, 0, 0, 0 };
}
//建哈夫曼树
for (i = n + 1; i <= m; ++i)
{
Select(HT, i - 1, s); s1 = s;
Select(HT, i - 1, s); s2 = s;
if (s1 > s2) swap(s1, s2);
HT[s1].parent = i; HT[s2].parent = i;
HT[i].lchild = s1; HT[i].rchild = s2;
HT[i].weight = HT[s1].weight + HT[s2].weight;
}
//从叶子结点到根逆向求哈夫曼编码
HC = (HuffmanCode)malloc((n + 1) * sizeof(char*));
char* cd = (char*)malloc(n * sizeof(char));
cd[n - 1] = '\0';
for (int i = 1; i <= n; ++i)
{
int start = n - 1, c;
uint f;
for (c = i, f = HT[i].parent; f != 0; c = f, f = HT[f].parent)
{
if (HT[f].lchild == c)
cd[--start] = '0';
else
cd[--start] = '1';
}
HC[i] = (char*)malloc((n - start) * sizeof(char));
strcpy(HC[i], &cd[start]);
}
free(cd);
}
int main()
{
int n;
uint w[200];
HuffmanTree HT;
HuffmanCode HC;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> w[i];
}
HuffmanCoding(HT, HC, w, n);
for (int i = 1; i <= n; i++)
{
cout << HC[i] << endl;
}
return 0;
}