引言:
在C++编程中,我们经常需要自定义数据结构的行为以满足特定的需求。优先队列(std::priority_queue
)是一种非常有用的容器适配器,它提供了队列的接口,但其中的元素总是按照某种顺序(通常是最大或最小)进行排序。然而,默认情况下,std::priority_queue
使用std::less<T>
(对于最大堆)或std::greater<T>
(对于最小堆)进行排序。但在很多情况下,我们可能需要根据自己的需求来定义排序规则。这时,仿函数就派上了用场。
仿函数(Function Object)简介:
仿函数是一种特殊的类,其对象可以像函数那样被调用。在C++中,我们只需要重载类的operator()
,就可以将该类的对象当作函数来使用。仿函数的一个常见用途是作为算法的谓词(predicate),比如排序和搜索算法中的比较函数。
优先队列(std::priority_queue
)简介:
std::priority_queue
是一个容器适配器,它提供队列的所有操作,包括push
、pop
、top
等,但其内部元素总是按照特定的顺序进行排序。默认情况下,最大元素总是在顶部(即最先被pop
出来),但我们可以通过提供自定义的比较函数或仿函数来改变这个行为。
优先队列与仿函数模拟
template<class T>
class less
{
public:
bool operator()(const T& x, const T& y)
{
return x < y;
}
};
template<class T>
class greater
{
public:
bool operator()(const T& x, const T& y)
{
return x > y;
}
};
template <class T, class Container = std::vector<T>, class Compare=less<T> >
class priority_queue
{
public:
void adjust_up(size_t child)
{
int partent = (child - 1) / 2;
while (child > 0)
{
if (comp(partent, child))
{
std::swap(c[partent], c[child]);
child = partent;
partent = (child - 1) / 2;
}
else
{
break;
}
}
}
void push(const T& x)
{
c.push_back(x);
adjust_up(c.size()-1);
}
void adjust_down(int parent)
{
int child = parent * 2 + 1;
while (child < c.size())
{
if (child + 1 < c.size() && comp(c[child], c[child + 1]))
{
++child;
}
if (comp(c[parent], c[child]))
{
std::swap(c[parent], c[child]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
void pop()
{
std::swap(c[0], c[c.size() - 1]);
c.pop_back();
adjust_down(0);
}
private:
Container c;
Compare comp;
};