zoukankan      html  css  js  c++  java
  • 哈夫曼树和哈夫曼编码(文件压缩)

    哈夫曼树(Huffman Tree)
    带权路径长度(WPL):设二叉树有n个叶子结点,每个叶子结点带有权值Wk,从根节点到每个叶子结点的长度为Lk,则每个叶子结点带权路径长度之和就是(wk* Lk)求和
    最优二叉树或哈夫曼树:WPL最小的二叉树

    哈夫曼树的构造:每次把权值最小的两棵二叉树合并

     1 HuffmanTree Huffman(MinHeap H)
     2 {
     3     //这里最小堆的元素类型为HuffmanTree,排序的原则是结点的权值数据
     4     //假设H->Size个权值已经存在在H->Data[]->weight里
     5     int i, N;
     6     HuffmanTree T;
     7 
     8     BuildMinHeap(H);        //根据结点的权值将H调整为最小堆
     9     N = H->Size;
    10     for (i = 1; i < N; i++)        //做H->Size - 1次合并
    11     {
    12         T = (HuffmanTree)malloc(sizeof(struct HTNode));        //创建一个新的哈夫曼结点
    13         T->Left = DeleteMin(H);        //将最小堆中的最小元素,即根节点删除后返回,作为这个哈夫曼结点的左子结点
    14         T->Right = DeleteMin(H);        //再次将最小堆中的根节点删除后返回,作为这个哈夫曼树的右子结点
    15         //哈夫曼节点的权值等于左右子节点的权值之和
    16         T->weight = T->Left->weight + T->Right->weight;
    17         Insert(H, T);
    18     }
    19 
    20     return DeleteMin(H);    //最小堆中最后一个元素即使指向哈夫曼树根节点的指针
    21 }

    哈夫曼树的特点:
    没有度为1的结点
    n个叶子结点的哈夫曼树共有2n-1个结点
    哈夫曼树的任意非叶结点的左右子树交换后仍是哈夫曼树
    对同一组权值,存在不同构的两棵哈夫曼树,但两棵树的WPL相等

    哈夫曼编码(文件压缩):
    给定一段字符串,如何对字符进行编码,可以使得该字符串的编码存储空间最少

    前缀码:(prefix code)任何字符的编码都不是另一字符编码的前缀,可避免二义性
    二叉树表示法:每个字符通过从根节点开始用0指示左分支,用1指示右分支而已记录路径的方法表示出来
    用二叉树进行编码:
    (1)左右分支:0、 1
    (2)字符只在叶结点上
    用哈夫曼树的规则构造这棵二叉树

    哈夫曼编码对应的解压过程:

     依次读入文件的二进制码,从哈夫曼树的根节点出发,若当前读入0,则走向左孩子,否则走向右孩子。

    一旦到达某一叶子时便译出相应的字符。然后重新从根出发继续下一个字符的译码,直至文件结束

  • 相关阅读:
    Android Studio 快捷键
    维基百科地址(应该是吧)
    Freeswitch常見問題解決辦法
    配置SIP网关拨打外部电话
    Freeswitch连接SIP软电话
    CentOS6.5安装freeswitch以及啟動
    hdu 4292: Food(Dinic + 链式前向星)
    hdu 2709:Sumsets(递推)
    hdu 2577:How to Type(动态规划)
    hdu 2955:Robberies(01背包)
  • 原文地址:https://www.cnblogs.com/hi3254014978/p/9543244.html
Copyright © 2011-2022 走看看