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

先来了解一下哈夫曼树.

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

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

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

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

哈夫曼树的构造;

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

代码:

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)

哈夫曼树的特点:

(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:任何字符的编码都不是另一字符编码的前缀

可以无二义地解码

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

时间: 2024-12-18 02:02:30

《数据结构复习笔记》--哈夫曼树,哈夫曼编码的相关文章

《大话数据结构》笔记(6-3)--树:赫夫曼树

代码实现: 第六章    树:赫夫曼树 赫夫曼树定义与原理 从树中一个结点到另一个结点之间的分支构成两个结点之间的路径,路径上的分支数目称作路径长度. 树的路径长度就是从树根到每一结点的路径长度之和. 对于带权的结点,结点的带权路径长度为从该结点到树根之间的路径长度与结点上权的乘积. 树的带权路径长度为树中所有叶子结点的带权路径长度之和. 假设有n个权值{w1, w2, ..., wn},构造一棵有n个叶子结点的二叉树,每个叶子结点带权wk ,每个叶子的路径长度为lk,则其中带权路径长度WPL最

数据结构&amp;&amp;哈弗曼树和哈弗曼编码

1.什么是哈夫曼树和哈弗曼编码 大家来看这样一道面试题(题目来自于<程序员面试宝典>).用二进制来编码字符串"abcdabaa",需要能够根据编码,解码回原来的字符串,最少需要多长的二进制字符串? A.12 B.14 C.18 D.24 解析:典型的哈弗曼编码问题:字符串"abcdabaa"有4个a.2个b.1个c.1个d.构造哈弗曼树如下图所示(图好丑).a编码0(1位),b编码10(2位),d编码111(3位).二进制字符串的总长度为1*4+2*2+

赫夫曼树的构建、编码、译码解析

当你開始看这篇博文的时候.我相信你对树及二叉树的基本概念已有所了解.我在这里就不再赘述. 我们主要对赫 夫曼树的特点.构建.编码.译码做一个具体的介绍,并附有代码,全部函数代码都通过了測试.我不保证全部代码是最优的(毕竟是我一个人苦思冥想出来的,我相信在大家的集思广益之下还有优化的空间),但我保证全部代码是正确的. 一.赫夫曼树的特点 赫夫曼树又称作最优二叉树,是一类带权路径长度最短的树. 首先给出路径和路径长度的概念.从树中一个节点到 还有一个节点之间的分支构成这两个节点之间的路径.路径上的分

哈夫曼树+哈夫曼编码

前天acm实验课,老师教了几种排序,抓的一套题上有一个哈夫曼树的题,正好之前离散数学也讲过哈夫曼树,这里我就结合课本,写一篇关于哈夫曼树的博客. 哈夫曼树的介绍 Huffman Tree,中文名是哈夫曼树或霍夫曼树,它是最优二叉树. 定义:给定n个权值作为n个叶子结点,构造一棵二叉树,若树的带权路径长度达到最小,则这棵树被称为哈夫曼树. 这个定义里面涉及到了几个陌生的概念,下面就是一颗哈夫曼树,我们来看图解答. (01) 路径和路径长度 定义:在一棵树中,从一个结点往下可以达到的孩子或孙子结点之

《数据结构复习笔记》--二叉搜索树

二叉搜索树:维基百科:click here 二叉查找树(Binary Search Tree),也称二叉搜索树.有序二叉树(ordered binary tree),排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的二叉树: 若任意节点的左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值: 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值: 任意节点的左.右子树也分别为二叉查找树. 没有键值相等的节点(no duplicate nodes

《数据结构复习笔记》--堆

把堆的相关知识在复习一下.加深理解 堆排序与快速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法.学习堆排序前, 先来了解一下二叉堆. 二叉堆的定义 二叉堆是完全二叉树或者是近似完全二叉树. 二叉堆满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值. 2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆). 当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆.当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆.下图展示

数据结构复习笔记--数组

最后还是决定在未来的道路上走向软件开发者这条路,从现在重新复习数据结构和算法. 关于数组有几个比较有意思的特点. 1.对于数组 int List[3],编译器将List[i]解释为指向一个地址为List + i*sizeof(int)的整数的指针. 对于int * List, int *List2[5],两个都是指向int 类型的变量,但是编译器会为后者分配五个整数存储空间. List2实际是上指向List2[0],List2 + i 实际上是&List2[i].在C语言中是不需要加上偏移量的.

《大话数据结构》笔记(6-1)--树:树

代码实现: https://github.com/Lyu0709/data-structure/blob/master/src/com/coding/basic/tree/Tree.java 第六章    树 树的定义 树的结点包含一个数据元素及若干指向其子树的分支. 结点拥有的子树数称为结点的度(degree). 度为0的结点称为叶结点(Leaf)或终端结点:度不为0的结点称为非终端结点或分支结点. 除根结点之外,分支结点也称为内部结点. 树的度是树内各结点的度的最大值. 结点的子树的根称为该

《大话数据结构》笔记(6-2)--树:二叉树

代码实现: 第六章    树:二叉树 定义 特点 二叉树的五种基本形态: 1. 空二叉树 2. 只有一个根结点 3. 根结点只有左子树 4. 根结点只有右子树 5. 根结点基友左子树又有右子树 特殊二叉树 斜树 所有结点都只有左子树的二叉树叫做左斜树.所有结点都只有右子树的二叉树叫做右斜树. 这两者统称为斜树. 斜树有很明显的特点,就是每一层都只有一个结点,结点的个数与二叉树的深度相同. 其实线性表结构可以理解为树的一种极其特殊的表现形式. 满二叉树 在一棵二叉树中,如果所有分支结点都存在左子树