HUffmanTree

来源:互联网 发布:python 验证码识别库 编辑:程序博客网 时间:2024/05/17 23:51

构造Huffman树
Huffman树构造算法:
1、由给定的n个权值{w1,w2,w3,…,wn}构造n棵只有根节点的扩充二叉树森林F=
{T1,T2,T3,…,Tn},其中每棵扩充二叉树Ti只有一个带权值wi的根节点,左右孩子均为
空。
2、重复以下步骤,直到F中只剩下一棵树为止:
a、在F中选取两棵根节点的权值最小的扩充二叉树,作为左右子树构造一棵新的二
叉树。将新二叉树的根节点的权值为其左右子树上根节点的权值之和。
b、在F中删除这两棵二叉树;

c、把新的二叉树加入到F中;

下面我们用代码实现HuffmanTree

源码:

#include<iostream>
#include<vector>
#include<queue>
#include<assert.h>
using namespace std;
template<class T>
class Less
{
public:
bool operator()(const T& left, const T& right)
{
bool b = left> right;
return b;
}
};
template<class T>
class Greater
{
public:
bool operator()(const T& left, const T& right)
{
return (left <= right);
}
};
template<class T, template<class> class Compare = Less>
class Heap
{
public:
Heap()
{}
Heap(const T arr[], size_t size)
{
for (size_t idx = 0; idx < size; ++idx)
{
_heap.push_back(arr[idx]);
}
size_t root = (size - 2) / 2;
for (int idx = root; idx >= 0; --idx)
{
_AdjustDown(idx, size);
}
}
void Insert(const T& data)
{
_heap.push_back(data);
size_t size = _heap.size();
if (size > 1)
{
_AdjustUp(size);
}
}
void Remove()
{
assert(!Empty());
size_t size = _heap.size();
if (size > 0)
{
std::swap(_heap[0], _heap[size - 1]);
_heap.pop_back();
_AdjustDown(0, size - 1);
}
else
{
_heap.pop_back();
}
}
bool Empty()
{
return _heap.empty();
}
size_t Size()const
{
return _heap.size();
}
T& Top()
{
return _heap[0];
}
private:
void _AdjustDown(size_t root, size_t size)
{
size_t parent = root;
size_t child = root * 2 + 1;
while (child < size)
{
if (child + 1 < size&&Compare<T>()(_heap[child + 1],_heap[child]))
{
child = child + 1;
}
if (Compare<T>()(_heap[child], _heap[parent]))
{
std::swap(_heap[parent], _heap[child]);
parent = child;
child = child * 2 + 1;
}
else
{
break;
}
}
}
void _AdjustUp(size_t size)
{
size_t parent = (size - 2) / 2;
size_t child = size - 1;
while (child != 0)
{
if (Compare<T>()(_heap[child], _heap[parent]))
{
std::swap(_heap[child], _heap[parent]);
child = parent;
parent = (child - 1) / 2;
}
else
{
break;
}
}
}


private:
std::vector<T> _heap;


};
template<class T>
struct HuffmanTreeNode
{
HuffmanTreeNode(const T& weight)
:_pLeft(NULL)
, _pRight(NULL)
, _weight(weight)
{}
HuffmanTreeNode<T>* _pLeft;
HuffmanTreeNode<T>* _pRight;
T _weight;
};
template<class T>
struct Compare
{
bool operator()(const T pLeft, const T pRight)
{
return (pLeft->_weight < pRight->_weight);
}
};
template<class T>
class HuffmanTree
{
public:
HuffmanTree()
{}
HuffmanTree(const T arr[], size_t size)
{
_pRoot = _CreatHuffmanTree(arr, size);
}
//层序遍历HuffmanTree
void LevelOrder()
{
if (_pRoot == NULL)
{
return;
}
HuffmanTreeNode<T>* pCur = _pRoot;
queue<HuffmanTreeNode<T>*> q;
q.push(_pRoot);
while (!q.empty())
{
pCur = q.front();
cout << pCur->_weight << " ";
if (pCur->_pLeft)
{
q.push(pCur->_pLeft);
}
if (pCur->_pRight)
{
q.push(pCur->_pRight);
}
q.pop();
}
}
//析构函数
~HuffmanTree()
{
_DestroyTree(_pRoot);
}
private:
HuffmanTreeNode<T>* _CreatHuffmanTree(const T arr[], size_t size)
{
if (size == 0)
{
return NULL;
}


Heap<HuffmanTreeNode<T>*, Compare> hp;
for (size_t idx = 0; idx < size; ++idx)
{
hp.Insert(new HuffmanTreeNode<T>(arr[idx]));
}
while (hp.Size()>1)
{
//从堆中取两个权值较小的数,
HuffmanTreeNode<T>* pLeft = hp.Top();
hp.Remove();
HuffmanTreeNode<T>* pRight = hp.Top();
hp.Remove();
HuffmanTreeNode<T>* parent = new HuffmanTreeNode<T>(pLeft->_weight + pRight->_weight);
parent->_pLeft = pLeft;
parent->_pRight = pRight;
hp.Insert(parent);
}
return hp.Top();
}


private:
void _DestroyTree(HuffmanTreeNode<T>* pRoot)
{
if (pRoot)
{
_DestroyTree(pRoot->_pLeft);
_DestroyTree(pRoot->_pRight);
delete[] pRoot;
pRoot = NULL;
}
}
private:
HuffmanTreeNode<T>* _pRoot;
};
void Funtest()
{
int arr[] = { 1,3,5,7,9};
HuffmanTree<int> huff(arr, sizeof(arr) / sizeof(arr[0]));
huff.LevelOrder();
}
int main()
{
Funtest();
system("pause");
return 0;
}

原创粉丝点击