一、定义
(1)专业解释
给定n个权值作为n的叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
(2)自己理解
Huffman树,也称最优二叉树,是加权路径长度最短的二叉树。
简单的来说就是权值越大路径越短(权值),这样整体最优(权值*路径长度的和最小)
二、贪心法则构建哈夫曼数
(1)什么是贪心法则
是指在问题求解时,总是做出当前看起来最好的选择。也就是说贪心算法做出的不是整体最优的的选择,而是某种意义上的局部最优解。贪心算法不是对所有的问题都能得到整体最优解。
(2)怎么构建哈夫曼树
从权值最小的值开始构建,开始的时候选择两个权值最低的两个构建一个局部哈夫曼树,然后将这个构建好的数的根节点(权重值为左右节点权重的相加)返回到原来的序列中,构建好的数就从序列中删除了,这样不断选择两个权重最小的两个进行构建,知道序列中的元素个数为0
三、大体结构
1、huffmanNode的声明
template<class T>
struct HuffmanNode
{
HuffmanNode<T>* _left;
HuffmanNode<T>* _right;
T _weight;//权值
public:
HuffmanNode(const T& w)
:_weight(w)
, _left(NULL)
, _right(NULL)
{}
};
2、huffmanTree的结构
#include"Heap.h"
template<class T>
class HuffmanTree
{
typedef HuffmanNode<T> Node;
public:
HuffmanTree();//默认构造函数
HuffmanTree(const T* a, size_t size);//建立huffmanTree
void GenerateHuffmanCode();//获取对应的huffman编码,找什么,怎么找
protected:
Node* _GreatTree(const T* a, size_t size);
protected:
Node* _root;
};
四、具体实现
1、默认构造函数
HuffmanTree()
:_root(NULL)
{}
2、构建huffmanTree(使用递归构建)
(1)主函数:
HuffmanTree(const T* a, size_t size)
{
_root = _GreatTree(a, size);
}
(2)递归函数
Node* _GreatTree(const T* a, size_t size)
{
struct Compare//建立小根堆
{
bool operator()(const Node* l, const Node* r)
{
return l->_weight < r->_weight;
}
};
Heap<Node*,Compare> minHeap;//保存的是节点,而不是T类型的具体的数据,若为数那么节点摘下来,那不是后面的数没有了
for (size_t i = 0; i < size; i++)
{
minHeap.Push(new Node(a[i]));
}
while (minHeap.Size()>1)//不能使用minHeap.Empty(),因为有两两配对,会剩下只有一个数的情况
{<span style="white-space:pre"> </span>//也就是节点数两两配对,最后会剩下一个root节点
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;
minHeap.Push(parent);
}
return minHeap.Top();
}