哈夫曼树又称最优二叉树,给定一组数,构造哈夫曼树构造出的树的权值最小即为哈夫曼树。
1:哈夫曼树的数据结构
#ifndef _HUFFMAN1_H_
#define _HUFFMAN1_H_
#include <stdio.h>
#include <stdlib.h>
typedef struct BTreeNode
{
int data;
struct BTreeNode* left;
struct BTreeNode* right;
}BTreeNode;
void PrintBTree_int(struct BTreeNode* BT);
BTreeNode* CreateHuffman(int a[], int n);
int WeightPathLength(struct BTreeNode* FBT, int len);
void HuffManCoding(struct BTreeNode* FBT, int len);
#endif
2:哈夫曼树的操作
#define _CRT_SECURE_NO_WARNINGS 1
#include "Huffman1.h"
//打印哈夫曼树
void PrintBTree_int(struct BTreeNode* BT)
{
if (BT != NULL)
{
printf("%d", BT->data);
if (BT->left != NULL || BT->right != NULL)
{
printf(" ( ");
PrintBTree_int(BT->left); //输出左子树
if (BT->right != NULL)
printf(" , ");
PrintBTree_int(BT->right); //输出右子树
printf(" ) ");
}
}
}
//构建哈夫曼树
BTreeNode* CreateHuffman(int a[], int n)
{
int i, j;
BTreeNode **b;
BTreeNode *q=NULL;
b = malloc(n*sizeof(BTreeNode));
for (i = 0; i < n; i++) //动态内存分配
{
b[i] = malloc(sizeof(BTreeNode));
b[i]->data = a[i];
b[i]->left = b[i]->right = NULL;
}
for (i = 1; i < n; i++)
{
//k1表示森林中具有最小权值的树根结点的下标,k2为次最小的下标
int k1 = -1, k2;
for (j = 0; j < n; j++) //让k1初始指向森林中第一棵树,k2指向第二棵
{
if (b[j] != NULL && k1 == -1)
{
k1 = j;
continue;
}
if (b[j] != NULL)
{
k2 = j;
break;
}
}
for (j = k2; j < n; j++) //构造最优解
{
if (b[j] != NULL)
{
if (b[j]->data < b[k1]->data)
{
k2 = k1;
k1 = j;
}
else if (b[j]->data < b[k2]->data)
k2 = j;
}
}
q = malloc(sizeof(BTreeNode));
q->data = b[k1]->data + b[k2]->data;
q->left = b[k1];
q->right = b[k2];
b[k1] = q;
b[k2] = NULL;
}
free(b);
return q;
}
//计算权值
int WeightPathLength(BTreeNode* FBT, int len)//len初始为0
{
if (FBT == NULL) //空树返回0
return 0;
else
{
if (FBT->left == NULL && FBT->right == NULL)
return FBT->data * len;
else
return WeightPathLength(FBT->left, len + 1) + WeightPathLength(FBT->right, len + 1);
}
}
//输出哈夫曼编码
void HuffManCoding(BTreeNode* FBT, int len)
{
static int a[10];
if (FBT != NULL)
{
if (FBT->left == NULL && FBT->right == NULL)
{
int i;
printf("结点的值为%d的编码:", FBT->data);
for (i = 0; i < len; i++)
printf("%d", a[i]);
printf("\n");
}
else
{
a[len] = 0;
HuffManCoding(FBT->left, len + 1);
a[len] = 1;
HuffManCoding(FBT->right, len + 1);
}
}
}