萌新学习笔记之哈夫曼树

哈夫曼树的定义:

假设有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;
}


原文地址:https://www.cnblogs.com/keyboarder-zsq/p/6777532.html