哈夫曼树的定义:
假设有n个权值{ w1,w2 , ... , wn},构造有n个叶结点的二叉树,每个叶结点的权值是n个权值之一,这样的二叉树可以构造很多棵,其中必有一棵是带权路径长度最小的,这棵二叉树就称为最优二叉树或哈夫曼树;typedef struct TreeNode* HuffmanTree;
struct TreeNode{
int Weight;
HuffmanTree Left;
HuffmanTree Right;
};
哈夫曼树的构造
(懒得写了,摘自百度百科,亲测很好):
假设有n个权值,则构造出的哈夫曼树有n个叶子结点。 n个权值分别设为 w1、w2、…、wn,则哈夫曼树的构造规则为:(1) 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点);
(2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;
(3)从森林中删除选取的两棵树,并将新树加入森林;
(4)重复(2)、(3)步,直到森林中只剩一棵树为止,该树即为所求得的哈夫曼树。
这里还会需要一个最小堆,来提供每次取最小的两个,因为是数据结构C语言版,所以那个最小堆,STL的priority_queue也不能用,实现起来很繁,也就不实现;
HuffmanTree Huffman(MinHeap H) //假设H-size 个权值已经存在H ->Element[]->weight 里;
{
int i;
HuffmanTree T;
BuildMinHeap(H); //将H -> Element[]按权值调整成最小堆
for(i=1 ; i< H->Size ; ++i) //做size-1次合并;
{
T=(HuffmanTree)malloc(sizeof(struct TreeNode)); //建立一个新结点
T->Left=DeleMin(H); //从堆中删除一个最小结点,然后作为左结点
T->Right=DeleMin(H); //同上
T->Weight=T->Left->Weight+T->Right->Weight; //计算新权值
Insert(H,T); //往最小堆插入新结点;
}
T=DeleMin(H); //最后从最小堆中取出;
return T;
}