堆的实现
#pragma once
#include <functional>
#include <vector>
namespace Test
{
template<class T, class Container = std::vector<T>, class Cmp = std::less<T>>
class priority_queue
{
public:
priority_queue(const Cmp& cmp = Cmp(), const Container& con = Container())
: _con(con)
, _cmp(cmp)
{}
template<class Iterator>
priority_queue(Iterator first, Iterator last, const Cmp& cmp = cmp(), const Container& con = Container())
: _con(con)
, _cmp(cmp)
{
_con.insert(_con.begin(), first, last);
int root = (_con.size() - 2) >> 1;
for (int i = root; i >= 0; --i)
_AdjustDown(root);
}
void push(const T& data)
{
_con.push_back(data);
_AdjustUp(_con.size() - 1);
}
void pop()
{
if (empty())
return;
swap(_con[0], _con[_con.size() - 1]);
_con.pop_back();
_AdjustDown(0);
}
const T& top()
{
return _con[0];
}
size_t size()
{
return _con.size();
}
bool empty()
{
return _con.empty();
}
private:
void _AdjustDown(int parent)
{
int child = parent * 2 + 1;
while (child < _con.size())
{
if (child + 1 < _con.size() && _cmp(_con[child] , _con[child + 1]))
child += 1;
if (_cmp(_con[parent] , _con[child]))
{
swap(_con[child], _con[parent]);
parent = child;
child = parent * 2 + 1;
}
else
{
return;
}
}
}
void _AdjustUp(int child)
{
int parent = (child - 1) >> 1;
while (parent >= 0)
{
if (_cmp(_con[parent] , _con[child]))
{
swap(_con[child], _con[parent]);
child = parent;
parent = (child - 1) >> 1;
}
else
{
return;
}
}
}
private:
Container _con;
Cmp _cmp;
};
}
测试代码
#include "priority_queue.h"
using namespace std;
#include <iostream>
void Testpriority_queue()
{
Test::priority_queue<int> p;
p.push(4);
p.push(3);
p.push(5);
p.push(9);
p.push(7);
p.push(0);
p.push(6);
p.push(1);
p.push(2);
cout << p.size() << endl;
cout << p.top() << endl;
p.pop();
p.pop();
cout << p.size() << endl;
cout << p.top() << endl;
}
void Testpriority_queue2()
{
Test::priority_queue<int, vector<int>, greater<int>> p;
p.push(4);
p.push(3);
p.push(5);
p.push(9);
p.push(7);
p.push(0);
p.push(6);
p.push(1);
p.push(2);
cout << p.size() << endl;
cout << p.top() << endl;
}
class Date
{
public:
Date(int year, int month, int day)
: _year(year)
, _month(month)
, _day(day)
{}
int Getday()
{
return _day;
}
private:
int _year;
int _month;
int _day;
};
class Greater
{
public:
bool operator()(Date& left, Date& right)
{
return left.Getday() > right.Getday();
}
};
void Testpriority_queue3()
{
Date d1(2020, 5, 6);
Date d2(2020, 5, 7);
Date d3(2020, 5, 8);
Test::priority_queue<Date, vector<Date>, Greater> p;
p.push(d1);
p.push(d2);
p.push(d3);
}
int main()
{
Testpriority_queue3();
return 0;
}