题目:假设有一个字母表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); } }
更多内容,去看原文吧,原文还给了实例