1.定义
不是传统的队列,先进先出,而是让优先级高的先出
其中less是大堆,greater是小堆
简单的使用一下:
void test_priority_queue()
{
//插入删除数据效率logN
priority_queue<int> q;
q.push(3);
q.push(2);
q.push(5);
q.push(4);
while (!q.empty())
{
cout << q.top() << " ";
q.pop();
}
cout << endl;
}
输出:默认是一个大堆 ,大的优先级高
但是我想小的优先级高
void test_priority_queue()
{
//插入删除数据效率logN
priority_queue<int,vector<int>,greater<int>> q;
q.push(3);
q.push(2);
q.push(5);
q.push(4);
while (!q.empty())
{
cout << q.top() << " ";
q.pop();
}
cout << endl;
}
输出:
2. priority_queue模拟实现
#pragma once
#include<vector>
#include<algorithm>
namespace bit
{
template<class T,class Container=vector<T>>
class priority_queue
{
public:
void adjust_up(int child)
{
int parent = (child - 1) / 2;
while (child > 0)//child=0就结束
{
if (_con[child] > _con[parent])
{
std::swap(_con[child], _con[parent]);
child = parent;
parent = (child - 1) / 2;
}
else
{
break;
}
}
}
void adjust_down(int parent)
{
//如果是大堆,就先选左右孩子中最大的,大的往上走
size_t child = parent* 2+1;
while(child<_con.size())
{
if (child + 1 < _con.size() && _con[child + 1] > _con[child])
{
child = child + 1;
}
if (_con[parent] < _con[child])
{
std::swap(_con[child], _con[parent]);
parent=child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
void push(const T& x)
{
_con.push_back(x);//插入数据,size就会++
//向上调整
adjust_up(_con.size()-1);
}
void pop()
{
//堆里面删除堆顶的数据,将堆顶的数据和最后一个数据一换,然后删除数组中最后一个数据,在进行向下调整
std::swap(_con[0], _con[_con.size() - 1]);
_con.pop_back();//尾删
//向下调整
adjust_down(0);
}
const T& top()
{
return _con[0];
}
bool empty()
{
return _con.empty();
}
size_t size()
{
return _con.size();
}
private:
Container _con;
};
}
void test_priority_queue()
{
bit::priority_queue<int> q;
q.push(3);
q.push(2);
q.push(5);
q.push(4);
while (!q.empty())
{
cout << q.top() << " ";
q.pop();
}
cout << endl;
}
3.仿函数
下面是一个简单的仿函数
class Less
{
public:
bool operator()(int x, int y)
{
return x < y;
}
};
int main()
{
Less less;
cout << less(2, 3) << endl;被转换成调用下面的函数
cout << less.operator()(2, 3) << endl;
return 0;
}
其中less是函数对象,因为是对象,但是像函数一样去使用。所以只要一个类重载了operator(),就可以叫仿函数。
但是下面的仿函数一般都要加模板,不然就太局限了
template<class T>
class Less
{
public:
bool operator()(const T& x, const T& y)
{
return x < y;
}
};
int main()
{
Less<int> less;
cout << less(2, 3) << endl;
return 0;
}
请问:仿函数到底有什么用途?
是为了替代函数指针
void test_priority_queue()
{
int a[] = { 1,2,6,2,1,5,9,4 };
//sort(a, a + 8);//默认sort是升序
sort(a, a + 8,greater<int>()); //降序
}
bit::priority_queue<int, vector<int>,greater<int>> q;
为什么greater<int>()要带括号呢,和上面有什么区别呢?
类型,只需要把仿函数的类型传递过去 ,模板参数
函数参数,传递的是对象
应用仿函数的举例二:
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
: _year(year)
, _month(month)
, _day(day)
{}
bool operator<(const Date& d)const
{
return (_year < d._year) ||
(_year == d._year && _month < d._month) ||
(_year == d._year && _month == d._month && _day < d._day);
}
bool operator>(const Date& d)const
{
return (_year > d._year) ||
(_year == d._year && _month > d._month) ||
(_year == d._year && _month == d._month && _day > d._day);
}
friend ostream& operator<<(ostream& _cout, const Date& d);
private:
int _year;
int _month;
int _day;
};
ostream& operator<<(ostream& _cout, const Date& d)
{
_cout << d._year << "-" << d._month << "-" << d._day;
return _cout;
}
struct PDateCompare
{
bool operator()(Date* p1, Date* p2)
{
return *p1 > *p2;
}
};
int main()
{
bit::priority_queue<Date> q1;
q1.push(Date(2018, 10, 9));
q1.push(Date(2018, 10, 8));
q1.push(Date(2018, 10, 10));
cout << q1.top() << endl;
bit::priority_queue<Date*, vector<Date*>, PDateCompare> q2;
q2.push(new Date(2018, 10, 9));
q2.push(new Date(2018, 10, 8));
q2.push(new Date(2018, 10, 10));
cout << *(q2.top()) << endl;
return 0;
}
输出:
使用仿函数
class PDateCompare
{
bool operator()(Date* p1, Date* p2)
{
return *p1 > *p2;
}
};
结果就不是随机值,比较的是指针解引用的值。