标签:
Huffman树又称最优树,是一类带权路径长度最短的树,带权路径长度为从该节点到树根之间的路径长度与节点上权值的成积。
那么如何构建一个Huffman树呢?就需要Huffman算法
1、利用给定的n个权值构成有n个二叉树的集合F,每个二叉树就只有一个带权值的根节点,其左右子树都为空。
2、选取两课根节点权值最小的树作为左右子树,且重置新的二叉树的根节点的权值为左右子树权值之和。
3、在集合F中删掉这两课子树,并将新得到的二叉树加入到F中去。
4、重复2、3操作直至F中只剩下一棵子树。
如下图:Huffman的构造过程(其中红色数字表示的是节点的权值)
Huffman存储:Huffman树中没有度为一的结点,一棵有n个叶子结点的Huffman树共有2n-1个结点,可以存储在一个大小为2n-1的一维数组中。
编码走一条从根路径出发到叶子节点的路径;译码走一条从叶子节点出发到根的路径,对于每个结点而言即需要知道其父亲结点又要知道其左右孩子结点。
Huffman树建立主要代码实现:
void CreateTree(const T* a, size_t size, const T& invalid) { assert(a); Heap<Node*, NodeCompare<T>> minHeap;//一个小堆的结构 for (size_t i = 0; i < size; ++i) { if (a[i] != invalid) { //将a[i]构建成节点,插入堆 Node* node = new Node(a[i]); minHeap.Push(node); } } while (minHeap.Size()>1) {//得到权值最小的两个元素作为左右子树 Node* left = minHeap.Top(); minHeap.Pop(); Node* right = minHeap.Top(); minHeap.Pop(); //利用左右子树的权值之和构造出结点 Node* parent = new Node(left->_weight + right->_weight);
//进行链接 parent->_left = left; parent->_right = right; left->_parent = parent; right->_parent = parent; minHeap.Push(parent); } _root = minHeap.Top(); }
Huffman编码:约定左分支表示字符‘0‘,右分支表示字符‘1‘,则可以从根节点到叶子节点的路径上分支字符组成的字符串作为该叶子结点字符的编码
标签:
原文地址:http://www.cnblogs.com/Blog-day/p/My_Blog_Days_19.html