码迷,mamicode.com
首页 > 其他好文 > 详细

《数据结构复习笔记》--哈夫曼树,哈夫曼编码

时间:2015-01-21 22:40:30      阅读:438      评论:0      收藏:0      [点我收藏+]

标签:数据结构 哈夫曼树   霍夫曼编码   

维基百科链接:click here

先来了解一下哈夫曼树.

带权路径长度(WPL):设二叉树有n个叶子结点,每个叶子结点带有权值 wk,从根结点到每个叶子结点的长度为 lk,则每个叶子结点的带权路径长度之和就是:

技术分享

最优二叉树或哈夫曼树: WPL最小的二叉树。

〖例〗有五个叶子结点,它们的权值为{1,2,3,4,5},用此权值序列可以构造出形状不同的多个二叉树。

技术分享

其中结果wpl最小值的是:33=(1+2)*3+(3)*2+(4+5)*2;

哈夫曼树的构造;

每次把权值最小的两棵二叉树合并,

代码:

<span style="font-size:12px;">typedef struct TreeNode *HuffmanTree;
struct TreeNode
{
    int Weight;
    HuffmanTree Left, Right;
}
HuffmanTree Huffman( MinHeap H )
{
    /* 假设H->Size个权值已经存在H->Elements[]->Weight里 */
    int i;
    HuffmanTree T;
    BuildMinHeap(H); /*将H->Elements[]按权值调整为最小堆*/
    for (i = 1; i < H->Size; i++)   /*做H->Size-1次合并*/
    {
        T = malloc( sizeof( struct TreeNode) ); /*建立新结点*/
        T->Left = DeleteMin(H);
        /*从最小堆中删除一个结点,作为新T的左子结点*/
        T->Right = DeleteMin(H);
        /*从最小堆中删除一个结点,作为新T的右子结点*/
        T->Weight = T->Left->Weight+T->Right->Weight;
        /*计算新权值*/
        Insert( H, T ); /*将新T插入最小堆*/
    }
    T = DeleteMin(H);
    return T;
}
整体复杂度为O(N logN)

</span>

哈夫曼树的特点:
(1)没有度为1的结点;
(2)哈夫曼树的任意非叶节点的左右子树交换后仍是哈夫曼树;
(3)n个叶子结点的哈夫曼树共有2n-1个结点;
(4)对同一组权值{w1 ,w2 , …… , wn},是否存在不同构的两棵哈夫曼树呢?
对一组权值{ 1, 2 , 3, 3 },不同构的两棵哈夫曼树:

 技术分享

再简单说一下哈夫曼编码(又称霍夫曼):

哈夫曼编码
比如给定一段字符串,如何对字符进行编码,可以使得该字符串的编码存储空间最少?
[例] 假设有一段文本,包含58个字符,并由以下7个字符构:a,e,i,s,t,空格(sp),换行(nl);这7个字符出现的次数不同。如何对这7个字符进行编码,使得总编码空间最少?
【分析】
(1)用等长ASCII编码:58 ×8 = 464位;
(2)用等长3位编码:58 ×3 = 174位;
(3)不等长编码:出现频率高的字符用的编码短些,出现频率低的字符则可以编码长些?

怎么进行不等长编码?   如何避免二义性?

前缀码prefix code:任何字符的编码都不是另一字符编码的前缀
可以无二义地解码

技术分享

可以看到,所有需要编码的字符都在构造的树的叶子节点。

下面举一个例子,说明一下构造一棵哈夫曼树的过程:

思路:根据不同的字符对应的数字,首先选择最小的两个数字,作为结点的两个儿子,结点就是两个权值之和,然后,在选择大小差不多的另一个数字作为i新结点的儿子,

和之前的和又构造一棵二叉树,依次递推上去,最后形成的就是一棵哈夫曼树。最后把每棵子二叉树的左右结点分别标记为0,1,形成每个字符的编码值,Cost 为所求权值总和,详解如下图

技术分享

《数据结构复习笔记》--哈夫曼树,哈夫曼编码

标签:数据结构 哈夫曼树   霍夫曼编码   

原文地址:http://blog.csdn.net/u013050857/article/details/42975503

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!