Huffman树
Huffman树,又称为最优二叉树,是加权路径长度最短的二叉树
构建Huffman树
- 选当前权值最小的两个结点,构建一个父亲结点,形成一颗树;该树父亲节点的权值是,左孩子和右孩子权值的和;
- 将构建的父亲节点的权值扔回,和剩余结点做比较,在选两个权值最小的,构成树
- 最终形成一颗树,叫Huffman树
树的特点
每个节点的权值是,以该节点为根节点的树,中所有叶子节点权值的和
权值越小,深度越深(编码越长);权值越大,深度越小(编码越短)
代码实现Huffman树
#pragma once
#include"Heap.h"
#include <functional>
template <class W>
struct HuffmanTreeNode
{
HuffmanTreeNode<W>* _left;
HuffmanTreeNode<W>* _right;
HuffmanTreeNode<W>* _parent;//三叉链,叶子结点生成Huffman编码需要三叉链(倒着往前)
W _w;//权值
HuffmanTreeNode(const W& w)
:_left(NULL)
, _right(NULL)
,_parent(NULL)
, _w(w)
{}
};
template<class W>
class HuffmanTree
{
typedef HuffmanTreeNode<W> Node;
public:
HuffmanTree()
:_root(NULL)
{}
HuffmanTree(W* a, size_t n,const W& invalid)
{
//用仿函数解决第二个模板参数的问题(比较指针内容)
struct NodeCompare
{
bool operator() (Node* l, Node* r)
{
return l->_w < r->_w;//建的是小堆
}
};
//先建一个小堆
Heap<Node*, NodeCompare> minHeap;//为什么模板第一个参数是指针?
for (size_t i = 0; i < n; ++i)
{
if (a[i] != invalid)//不是非法值才能往堆里放,才能建HuffmanTree
{
minHeap.Push(new Node(a[i]));
}
}
while (minHeap.Size()>1)
{
Node* left = minHeap.Top();
minHeap.Pop();
Node* right = minHeap.Top();
minHeap.Pop();
Node* parent = new Node(left->_w + right->_w);
parent->_left = left;
parent->_right = right;
left->_parent = parent;
right->_parent = parent;
minHeap.Push(parent);
}
_root = minHeap.Top();//小堆内的最后一个结点(是个指针)
}
Node* GetRoot()
{
return _root;
}
protected :
Node* _root;
};