zoukankan      html  css  js  c++  java
  • 算法导论16.35huffman树的表示

    题目:假设有一个字母表C={0,1,2,3,4,...,n-1}上的最优前缀编码,我们想用尽可能少的位来传输。
    证明:C上的任意一个最优前缀编码都可由 2n-1+n*ceil(log(n)) 个位的序列来表示。(提示:用2n-1位说明树的结构,通过树的遍历来发现)

    解答:
    http://stackoverflow.com/questions/759707/efficient-way-of-storing-huffman-tree?answertab=votes#tab-top

    翻译一下:
    对字母表n个字符用定长二进制编码,每个字符用N=ceil(log(n))个位(bit),C对应的huffman树有n个叶子,可以证明:任何非空二叉树,度为2的结点比叶结点个数少1,因此该树有n-1个内结点
    每个结点用1个bit表示其是否是叶结点,1--是叶结点,0--不是叶结点

    从根节点开始,处理当前结点:
    1、如果是叶结点,输出1(1个bit),紧跟着是该字符的编码(N=ceil(log(n))个bit)
    2、如果是内部结点,输出0(1个bit),递归处理其左孩子(先)和右孩子(后)

    恢复出这棵树:
    1、读一个bit,如果是1,再读N个bit,返回新结点,值为N个bit对应的字符,没有孩子
    2、如果是0,递归处理左右孩子,返回新结点(有左右孩子),该结点无字符(内结点嘛)
    下面是原作者给的伪代码:
    //对树编码
    void EncodeNode(Node node, BitWriter writer)
    {
        if (node.IsLeafNode)
        {
            writer.WriteBit(1);
            writer.WriteByte(node.Value);
        }
        else
        {
            writer.WriteBit(0);
            EncodeNode(node.LeftChild, writer);
            EncodeNode(node.Right, writer);
        }
    }
    //恢复树
    Node ReadNode(BitReader reader)
    {
        if (reader.ReadBit() == 1)
        {
            return new Node(reader.ReadByte(), null, null);
        }
        else
        {
            Node leftChild = ReadNode(reader);
            Node rightChild = ReadNode(reader);
            return new Node(0, leftChild, rightChild);
        }
    }

    更多内容,去看原文吧,原文还给了实例





  • 相关阅读:
    CSS3旋转动画
    CSS3的动画属性
    CSS选择器
    JS事件委托
    js 轮播图效果
    JS事件冒泡和事件捕获
    JS自定义播放器
    js闭包for循环只执行最后一个值得解决方法
    交通红绿灯
    汉明距
  • 原文地址:https://www.cnblogs.com/fstang/p/2808603.html
Copyright © 2011-2022 走看看