模拟 priority_queue
底层维护一个vector,通过向上调整算法,向下调整算法维护堆结构。
提供基本接口。
#include <algorithm>
#include <functional>
#include <iostream>
#include <queue>
#include <cassert>
namespace my
{
template<class T>
struct Less
{
bool operator()(const T& x1, const T& x2)
{
return x1 < x2;
}
};
template<class T>
struct Greater
{
bool operator()(const T& x1, const T& x2)
{
return x1 > x2;
}
};
template<class T, class Container = vector<T>, class Compare = std::less<T>>
class priority_queue
{
public:
priority_queue() {}
template<class InputIterator>
priority_queue(InputIterator begin, InputIterator end)
{
while (begin != end)
{
_con.push_back(*begin);
begin++;
}
for (int i = (size() - 1 - 1) / 2; i >= 0; i--)
adjustDown(size(), i);
}
void push(const T& x)
{
_con.push_back(x);
adjustUp(_con.size() - 1);
}
void pop()
{
std::swap(_con[0], _con[size() - 1]);
adjustDown(size() - 1, 0);
_con.pop_back();
}
const T& top()
{
assert(!empty());
return _con[0];
}
size_t size()
{
return _con.size();
}
bool empty()
{
return _con.empty();
}
private:
void adjustDown(int n, int parent)
{
Compare cmp;
int child = parent * 2 + 1;
while (child < n)
{
if (child + 1 < n && cmp(_con[child], _con[child + 1]))
child++;
if (cmp(_con[parent], _con[child]))
{
std::swap(_con[child], _con[parent]);
parent = child;
child = child * 2 + 1;
}
else
{
break;
}
}
}
void adjustUp(int child)
{
Compare cmp;
int parent = (child - 1) / 2;
while (child > 0)
{
if (cmp(_con[parent], _con[child]))
{
std::swap(_con[parent], _con[child]);
child = parent;
parent = (parent - 1) / 2;
}
else
{
break;
}
}
}
private:
Container _con;
};
}