堆的实现借助了库函数vector,对于堆分为大堆与小堆,大堆是指根元素大于左右子树元素,反之,则为小树。以大堆的建立为例子,利用一个数组以及数组的下表表示堆所对应的节点的序号,首先,以数组的最末一个元素,相对应堆的叶节点,计算出叶节点的根节点,然后,以此根节点为例,将这个子树生成大堆,再找出下个根节点,以此类推,直到找到最终的根节点位置,相应的代码如下:
同时,本例利用了仿函数,同时,也能够生成小堆。
template <class T>
struct Less
{
bool operator()(const T &l, const T &s)
{
return l < s;
}
};
template <class T>
struct Greater
{
bool operator()(const T &l,const T &s)
{
return l >s;
}
};
template <class T,class Com=Greater<T>>
class Heap
{
protected:
vector<T> _a;
Com _com;
void _creatdown( int parent)
{
int child = 2 * parent + 1;
while(child < _a.size())
{
if (child+1<_a.size()&&_com(_a[child+1] , _a[child]))
{
++child;
}
if (_com(_a[child],_a[parent]))
{
swap(_a[child], _a[parent]);
parent = child;
child = 2 * parent + 1;
}
else
{
break;
}
}
}
void _creatup(int child)
{
int parent = (child - 1) / 2;
while (child>0)
{
if (_com(_a[child] , _a[parent]))
{
swap(_a[child], _a[parent])
child = parent;
parent = (child - 1) / 2;
}
else
{
break;
}
}
}
public:
Heap()
{}
Heap(T *a, int size)
{
for (int i = 0; i < size; i++)
{
_a.push_back(a[i]);
}
for (int i = (_a.size() - 2) / 2; i >= 0; i--)
_creatdown(i);
}
void push(const T &x)
{
_a.push_back(x);
_creatdown(_a.size()-1);
}
void print()
{
for (int i = 0; i < _a.size();i++)
cout << _a[i]<<" ";
}
void pop()
{
swap(_a[0], _a[_a.size() - 1]);
_a.pop_back();
_creatup(0);
}
};
原文地址:http://10810512.blog.51cto.com/10800512/1771205