目录
代码
#include<bits/stdc++.h>
using namespace std;
typedef char* HuffmanCode;
const int MAXN = 110;
typedef struct {
int weight;
int lchild, rchild, parent;
}HuffmanNode, * HuffmanTree;
void seletMin(HuffmanTree HT, int n, int& s1, int& s2) {
int min = INT32_MAX;
for (int i = 1; i <= n; ++i) {
if (HT[i].parent == 0 && min > HT[i].weight) {
min = HT[i].weight;
s1 = i;
}
}
min = INT32_MAX;
for (int j = 1; j <= n; ++j) {
if (HT[j].parent == 0 && min > HT[j].weight && j != s1) {
min = HT[j].weight;
s2 = j;
}
}
if (s1 > s2) {
swap(s1, s2);
}
}
void HuffmanCoding(HuffmanTree& HT, HuffmanCode*& HC, int w[], int n) {
if (n <= 1) return;
int m = 2 * n - 1;
//0号单元未用
HT = new HuffmanNode[m + 1];
for (int i = 1; i <= n; ++i) {
HT[i].weight = w[i];
HT[i].lchild = HT[i].rchild = HT[i].parent = 0;
}
for (int i = n + 1; i <= m; ++i) {
HT[i].lchild = HT[i].rchild = HT[i].parent = 0;
}
for (int i = n + 1; i <= m; ++i)//建立哈夫曼树
{
int s1, s2;
//在HT[1~i-1]中选择parent为0且weight最小的两个结点,其序号分别为s1,s2
seletMin(HT, i - 1, s1, s2);
HT[s1].parent = HT[s2].parent = i;
HT[i].lchild = s1;
HT[i].rchild = s2;
HT[i].weight = HT[s1].weight + HT[s2].weight;
}
HC = new HuffmanCode[n + 1];
char* cd = new char[n];//分配编码工作空间
cd[n - 1] = '\0';//编码结束符
for (int i = 1; i <= n; ++i)//逐个字符求哈夫曼编码
{
int star = n - 1;//编码结束位置
for (int c = i, f = HT[i].parent; f != 0; c = f, f = HT[f].parent)
{
//从叶结点到根逆向求编码
if (HT[f].lchild == c) {
cd[--star] = '0';
}
else {
cd[--star] = '1';
}
}
//为第i个字符串编码分配空间
HC[i] = new char[n - star];
//从cd复制编码(串)到HC
strcpy(HC[i], cd + star);
}
delete[]cd;//释放工作空间
}
int main() {
HuffmanTree HT;
HuffmanCode* HC;
int n;
int data[MAXN];
while (scanf("%d", &n) != EOF) {
for (int i = 1; i <= n; ++i) {
scanf("%d", &data[i]);
}
HuffmanCoding(HT, HC, data, n);
for (int j = 1; j <= n; ++j) {
//printf("%s\n", HC[j]);
std::cout << HC[j] << std::endl;
}
delete(HT);
delete(HC);
}
return 0;
}