C++版本的堆的增加和删除实现:
#ifndef __CPREQUE_H__
#define __CPREQUE_H__
#include <vector>
#include <functional>
template<typename T, typename _Container=vector<T>, typename Rule=greater<T> >
class CPreQue
{
private:
Rule m_tRule;
_Container m_tContainer;
public:
CPreQue(){}
CPreQue(Rule tRule) :m_tRule(tRule){}
public:
bool Empty(); //是否为空
size_t Size() const; //堆的大小
void Push(T tData); //压入
void Pop(); //弹出
T& Top(); //首部元素
};
template<typename T, typename _Container/*=vector<T>*/, typename Rule/*=less<T> */>
T& CPreQue<T, _Container, Rule>::Top()
{
return m_tContainer.front();
}
template<typename T, typename _Container/*=vector<T>*/, typename Rule/*=less<T> */>
void CPreQue<T, _Container, Rule>::Pop()
{
if (m_tContainer.empty())
{
return;
}
size_t iFather = 0;
size_t iChild = iFather * 2 + 1;
//判断条件要忽略容器的最后一个元素,因为最后一个元素作为标记,最后进行升起操作
while (iChild < m_tContainer.size()-1)
{
//二叉堆的右节点存在且与左节点相比符合条件,则取右节点
if (((iChild + 1)<m_tContainer.size())
&& m_tRule(m_tContainer[iChild + 1], m_tContainer[iChild]))
{
++iChild;
}
//容器的尾部元素相比当前节点满足判断条件,退出循环,否则循环至倒数第二个元素
if (m_tRule(m_tContainer.back(), m_tContainer[iChild]))
break;
m_tContainer[iFather] = m_tContainer[iChild];
iFather = iChild;
iChild = iFather * 2 + 1;
}
//将最后一个元素的值赋给当前所在节点,并弹出最后一个元素。
m_tContainer[iFather] = m_tContainer.back();
m_tContainer.pop_back();
}
template<typename T, typename _Container/*=vector<T>*/, typename Rule/*=less<T> */>
void CPreQue<T, _Container, Rule>::Push(T tData)
{
m_tContainer.push_back(tData);
int iChild = m_tContainer.size() - 1;
int iFather = (iChild - 1) / 2;
while (iChild > 0)
{ //节点下沉操作
if (m_tRule(tData, m_tContainer[iFather]))
{
m_tContainer[iChild] = m_tContainer[iFather];
}
else
{
break;
}
iChild = iFather;
iFather = (iChild - 1) / 2;
}
m_tContainer[iChild] = tData;
}
template<typename T, typename _Container/*=vector<T>*/, typename Rule/*=less<T> */>
size_t CPreQue<T, _Container, Rule>::Size() const
{
return m_tContainer.size();
}
template<typename T, typename _Container/*=vector<T>*/, typename Rule/*=less<T> */>
bool CPreQue<T, _Container, Rule>::Empty()
{
return m_tContainer.empty();
}
最后部分代码可以自定义容器,以及排序规则。