//普通的模板参数
template<class T>
struct Less
{
bool operator()(const T& left,const T& right)
{
return left < right;
}
};
template<class T>
struct Greater
{
bool operator()(const T& left,const T& right)
{
return left > right;
}
};
template<class T,class Compare = Less<T>>//默认为小堆
class Heap
{
public:
Heap()
{}
Heap(const T array[],size_t size)
{
_heap.resize (size);
for(int i=0;i<size;i++)
{
//_heap.push_back (array[i]);
_heap[i] = array[i];
}
int root = (_heap.size ()-2)>>1;
for(;root>=0;root--)
{
_AdjustDown(root);
}
}
size_t Size()const
{
return _heap.size ();
}
bool Empty()const
{
return _heap.empty ();
}
void Insert(const T& data)
{
//先尾插入元素
//再向上调整
_heap.push_back (data);
//int root = (_heap.size ()-2)>>1;
//for(;root>=0;root--)
//{
// _AdjustDown(root);
//}
_AdjustUp(_heap.size ()-1);
}
void Remove()
{
//如果堆为空则不操作
if(_heap.size ()==0)
return ;
//如果只有根节点和其孩子则交换后直接删除最后一个节点
if(_heap.size ()<=2)
{
std::swap (_heap[0],_heap[_heap.size ()-1]);
_heap.pop_back ();
}
//如果节点数大于2个,则先交换根元素和尾元素,再删除尾元素,
//最后重新调整堆结构
else
{
std::swap (_heap[0],_heap[_heap.size ()-1]);
_heap.pop_back ();
//int root = (_heap.size ()-2)>>1;
//for(;root>=0;root--)
// _AdjustDown(root);
int child = _heap.size ()-1;
_AdjustUp(child);
}
}
const T& Top()const
{
assert(!Empty());
return _heap[0];
}
private:
void _AdjustDown(size_t parent)
{
size_t child = parent*2+1;
while(child<_heap.size ())
{
//Compare com;//可以用无名对象调用
//如果右孩子存在则找左右孩子中最小的节点
if(child+1<_heap.size () && Compare()(_heap[child+1],_heap[child]))
child+=1;
if(Compare()(_heap[child],_heap[parent]))
{
std::swap (_heap[parent],_heap[child]);
parent = child;
child = parent*2+1;
}
else
return ;
}
}
void _AdjustUp(size_t child)
{
while(child>=1)
{
size_t parent = (child-1)>>1;
if(child+1<_heap.size ()&&Compare()(_heap[child+1],_heap[child]))
child+=1;
if(Compare()(_heap[child],_heap[parent]))
std::swap (_heap[parent],_heap[child]);
child = parent;
}
}
private:
std::vector <T> _heap;
};
//模板的模板参数
template<class T>
struct Less
{
bool operator()(const T& left,const T& right)
{
return left < right;
}
};
template<class T>
struct Greater
{
bool operator()(const T& left,const T& right)
{
return left > right;
}
};
template<class T,template<class>class Compare>
//可以传入实时参数模板,但不能用无名对象调用
class Heap
{
public:
Heap()
{}
Heap(const T array[],size_t size)
{
_heap.resize (size);
for(int i=0;i<size;i++)
{
//_heap.push_back (array[i]);
_heap[i] = array[i];
}
int root = (_heap.size ()-2)>>1;
for(;root>=0;root--)
{
_AdjustDown(root);
}
}
size_t Size()const
{
return _heap.size ();
}
bool Empty()const
{
return _heap.empty ();
}
void Insert(const T& data)
{
//先尾插入元素
//再向上调整
_heap.push_back (data);
//int root = (_heap.size ()-2)>>1;
//for(;root>=0;root--)
//{
// _AdjustDown(root);
//}
_AdjustUp(_heap.size ()-1);
}
void Remove()
{
//如果堆为空则不操作
if(_heap.size ()==0)
return ;
//如果只有根节点和其孩子则交换后直接删除最后一个节点
if(_heap.size ()<=2)
{
std::swap (_heap[0],_heap[_heap.size ()-1]);
_heap.pop_back ();
}
//如果节点数大于2个,则先交换根元素和尾元素,再删除尾元素,
//最后重新调整堆结构
else
{
std::swap (_heap[0],_heap[_heap.size ()-1]);
_heap.pop_back ();
//int root = (_heap.size ()-2)>>1;
//for(;root>=0;root--)
// _AdjustDown(root);
int child = _heap.size ()-1;
_AdjustUp(child);
}
}
const T& Top()const
{
assert(!Empty());
return _heap[0];
}
private:
void _AdjustDown(size_t parent)
{
size_t child = parent*2+1;
while(child<_heap.size ())
{
Compare<T> com;
//如果右孩子存在则找左右孩子中最小的节点
if(child+1<_heap.size () && com(_heap[child+1],_heap[child]))
child+=1;
if(com(_heap[child],_heap[parent]))
{
std::swap (_heap[parent],_heap[child]);
parent = child;
child = parent*2+1;
}
else
return ;
}
}
void _AdjustUp(size_t child)
{
while(child>=1)
{
Compare<T> com;
size_t parent = (child-1)>>1;
if(com(_heap[child],_heap[parent]))
std::swap (_heap[parent],_heap[child]);
child = parent;
}
}
private:
std::vector <T> _heap;
};