哈夫曼树又叫最优树,是一类带权路径长度最短的树,在某些问题中,用哈夫曼树可以得到最佳判定算法。
首先定义HTnode和Huffmancode
typedef struct {
double weight;
int parent, lchild, rchild;
}HTnode, * Huffmantree;
typedef char**Huffmancode;
建立一个函数在n个数中找到两个最小的。
void selct(Huffmantree &HT,int n,int &x1,int &x2)
{
double min1 = MIN, min2 = MIN;
for (int i = 1; i <= n; i++)
{
if (HT[i].parent == 0 && HT[i].weight < min1)
{
min1 = HT[i].weight;
x1 = i;
}
}
for (int i = 1; i <= n; i++)
{
if (HT[i].parent == 0 && HT[i].weight < min2&& i!=x1)
{
min2 = HT[i].weight;
x2 = i;
}
}
if (x1 > x2)
{
int c = x2;
x2 = x1;
x1 = c;
}
}
创建哈夫曼树
void creatHT(Huffmantree &HT, int n,double *s)
{
if (n <= 1)return;
int m;
m = 2 * n - 1;
HT = (Huffmantree)malloc((m + 1) * sizeof(HTnode));
assert(HT != NULL);
for (int i = 1; i <= n; i++)
HT[i].weight = s[i-1];
for (int i = 1; i <= m; i++)
{
HT[i].parent = 0;
HT[i].lchild = 0;
HT[i].rchild = 0;
}
for (int i = n+1; i <= m; i++)
{
int x1, x2;
selct(HT, i-1, x1, x2);
HT[i].weight = HT[x1].weight + HT[x2].weight;
HT[x1].parent = i;
HT[x2].parent = i;
HT[i].lchild = x1;
HT[i].rchild = x2;
}
}
将哈夫曼编码保存起来
void Hcode(Huffmantree &HT,Huffmancode &HC, int n)
{
int temp, c, f,m;
m = 2 * n - 1;
HC = (char**)malloc(sizeof(char*) * n);
assert(HC);
for (int i = 1; i <= n; i++)
{
char* code = (char*)malloc(sizeof(char) * n);
assert(code ); //!= NULL
HC[i] = (char*)malloc(sizeof(char) * n);
assert(HC[i]);
code[n-1] = '\0';
temp = n-1;
c = i;
f = HT[i].parent;
while (f)
{
if (HT[f].lchild == c)
code[--temp] = '0';
else
code[--temp] = '1';
c = f;
f= HT[f].parent;
}
strcpy(HC[i], &code[temp] );
free(code);
}
}
最后是主函数
int main()
{
int n,m;
scanf("%d", &n);
m = 2 * n - 1;
double *s = (double*)malloc(n * sizeof(double));
assert(s != NULL);
for (int i = 0; i < n; i++)
{
scanf("%lf", &s[i]);
}
Huffmantree HT;
creatHT(HT, n, s);
printf("序号 权值 父节点 左孩子 右孩子\n");
for (int i = 1; i <= m; i++)
{
printf("%3d %9.2f %2d %2d %2d\n", i,
HT[i].weight, HT[i].parent, HT[i].lchild, HT[i].rchild);
}
Huffmancode HC;
Hcode(HT, HC, n);
for (int i = 1; i <= n; i++)
{
printf("%d=%s\n",i, HC[i]);
}
free(s);
free(HT);
return 0;
}
输出样例