优先级队列的自我实现
代码如下:
Priority_Queue.h文件:
#pragma once
#include <vector>
namespace bite
{
template<class T, class Container = std::vector<T>, class Com = std::less<T>>
class priority_queue
{
public:
priority_queue()
{}
template<class iterator>
priority_queue(iterator first, iterator last)
:_con(first, last)
{
//调整成为堆
//1.寻找调整位置,第一个非叶子节点
int size = _con.size();
int root = (size - 1 - 1) / 2;
for (; root >= 0; ++root)
{
_AdjustDown(root);
}
}
//向上调整
void push(const T& data)
{
_con.push_back(data);
int child = _con.size() - 1;
int parent = (child - 1) / 2;
while (child)
{
if (_con[parent] < _con[child])
{
std::swap(_con[parent], _con[child]);
child = parent;
parent = (child - 1) / 2;
}
else
{
return;
}
}
}
void pop()
{
if (_con.empty())
return;
std::swap(_con.front(), _con.back());
_con.pop_back();
_AdjustDown(0);
}
const T& top()const
{
return _con.front();
}
size_t size()const
{
return _con.size();
}
private:
void _AdjustDown(int parent)
{
//默认情况下标记左孩子,右孩子可能不存在
size_t child = parent * 2 + 1;
//向下调整不越界
while (child < _con.size())
{
//找左右孩子较大的
if (child + 1 < _con.size() && _con[child] < _con[child + 1])
{
child += 1;
}
//用较大孩子和双亲比较
if (_con[child] > _con[parent])
{
std::swap(_con[child], _con[parent]);
//交换后继续调整
parent = child;
child = parent * 2 + 1;
}
else
{
return;
}
}
}
private:
Container _con;
};
}
测试结果:
如果要改变比较方式,只需要自定义比较器,这里用仿函数的方式给出:
template<class T>
class Greater
{
public:
bool operator()(const T& left, const T& right)
{
return left > right;
}
};
namespace bite
{
template<class T, class Container = std::vector<T>, class Com = std::less<T>>
class priority_queue
{
public:
priority_queue()
{}
template<class Iterator>
priority_queue(Iterator first, Iterator last)
: _con(first, last)
{
// 将_con中的元素调整成堆
// 1. 找调整的位置
int size = _con.size();
int root = ((size - 2) >> 1);
for (; root >= 0; --root)
_AdjustDown(root);
}
void push(const T& data)
{
_con.push_back(data);
int child = _con.size() - 1;
int parent = ((child - 1) >> 1);
while (child)
{
if (Com()( _con[parent], _con[child]))
{
std::swap(_con[parent], _con[child]);
child = parent;
parent = ((child - 1) >> 1);
}
else
{
return;
}
}
}
void pop()
{
if (empty())
return;
std::swap(_con.front(), _con.back());
_con.pop_back();
_AdjustDown(0);
}
const T& top()const
{
return _con.front();
}
size_t size()const
{
return _con.size();
}
bool empty()const
{
return _con.empty();
}
private:
void _AdjustDown(int parent)
{
// 默认情况下:child标记左孩子
size_t child = parent * 2 + 1;
while (child < _con.size())
{
// 找左右孩子中较大的孩子
Com com;
if (child+1 < _con.size() && com(_con[child], _con[child + 1]))
child += 1;
// 用较大的孩子和双亲比较
if (com(_con[parent], _con[child]))
{
std::swap(_con[parent], _con[child]);
parent = child;
child = parent * 2 + 1;
}
else
{
return;
}
}
}
private:
Container _con;
};
}