哈弗曼树(Huffman tree):是最优二叉树,加权路径最短的二叉树。
贪心算法:是指在问题求解时,总是做出当前看起来最好的选择,即为贪心算法做出的不是整体最优的选择,而是某种意义上的局部最优解,贪心算法不是对所有的问题都能得到整体最优解。
思想:这里使用贪心算法构建哈弗曼树,运用最小堆的思想,建立最小堆,每次从堆中找最小的两个节点构造新结点,新结点再放回堆中,并连接两个旧的结点,按相同方法依次连接,直到剩下最后一个结点作为根结点,最后构造完成为哈夫曼树。
代码如下(此处引用前自己构造的堆,引用头文件Heap.h,前面博客已经写过):
#include<iostream>
#include <assert.h>
#include "Heap.h"
template <class T>
struct HuffmanTreeNode
{
T _weight; //权重
//三叉链
HuffmanTreeNode<T>* _left;
HuffmanTreeNode<T>* _right;
HuffmanTreeNode<T>* _parent;
HuffmanTreeNode(const T& x)
:_weight(x)
,_left(NULL)
,_right(NULL)
,_parent(NULL)
{}
};
template <class T>
class HuffmanTree
{
typedef HuffmanTreeNode<T> Node;
public:
HuffmanTree()
:_root(NULL)
{}
HuffmanTree(T* a,size_t n,const T& invalid)
{
assert(a);
struct Compare
{
bool operator()(Node* l1,Node* l2)
{
return l1->_weight<l2->_weight; //比较结点中的权值
}
};
//建小堆
Heap<Node*,Compare> hp;//堆中存储哈夫曼结点指针
for(size_t i=0;i<n;++i)
{
if(a[i]!=invalid)
{
hp.Push(new Node(a[i]));
}
}
//选最小的两个数据建哈夫曼树
while(hp.Size()>1)
{
Node* left=hp.Top();
hp.Pop();
Node* right=hp.Top();
hp.Pop();
Node* parent=new Node(left->_weight+right->_weight);
hp.Push(parent);
parent->_left=left;
parent->_right=right;
left->_parent=parent;
right->_parent=parent;
}
_root=hp.Top();//堆里最后一个结点即为根结点
hp.Pop();
}
~HuffmanTree()
{
_Destory(_root);
_root=NULL;
}
Node* GetRoot()
{
return _root;
}
protected:
void _Destory(Node* root)
{
if(root==NULL)
return;
_Destory(root->_left);
_Destory(root->_right);
if(root->_left==NULL&&root->_right==NULL)
{
delete root;
root=NULL;
}
}
protected:
Node* _root;
};
void TestHuffman()
{
int a[]={0,1,2,3,4,0,0,};
HuffmanTree<int> Htree(a,sizeof(a)/sizeof(a[0]),0);
}
int main()
{
TestHuffman();
system("pause");
return 0;
}