算法导论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);
    }
}

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





原文地址:https://www.cnblogs.com/fstang/p/2808603.html