哈弗曼树(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; }