马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
目录
1.仿函数
1.1仿函数的介绍
1.2自定义类型利用仿函数
1.3自定义支持比力巨细,但是比力的逻辑不是自己想要的逻辑
2.优先级队列priority_queue
2.1priority_queue的介绍
2.2priority_queue的利用
2.3priority_queue的模拟实现
1.仿函数
1.1仿函数的介绍
仿函数的本质是一个类模板,只是这个类重载了operator(),以是当利用一个它的对象时看起来像利用和函数一样,以是被称为仿函数。
下面通过仿函数的形式来写一个小于和大于的比力:
- #include <iostream>
- using namepsace std;
- 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;
- }
- };
- int main()
- {
- Less<int> less_func;
- Greater<int> greater_fun;
- int a = 5;
- int b = 10;
- cout << less_func(a, b) << endl;
- cout << greater_fun(a, b) << endl;
- return 0;
- }
复制代码
1.2自定义类型利用仿函数
自定义类型必要利用仿函数进行比力时,必要在自定义类型内里提供<和>等比力运算符的重载。比方对日期类进行比力:
- #include <iostream>
- using namespace std;
- 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;
- }
- };
- class Date
- {
- friend ostream& operator<<(ostream& _cout, const Date& d);
- 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);
- }
- private:
- int _year;
- int _month;
- int _day;
- };
- int main()
- {
- Less<Date> less_func;
- Greater<Date> greater_func;
- Date d1(2024, 9, 10);
- Date d2(2024, 8, 15);
- cout << less_func(d1, d2) << endl;
- cout << greater_func(d1, d2) << endl;
- return 0;
- }
复制代码
1.3自定义支持比力巨细,但是比力的逻辑不是自己想要的逻辑
这个时候仿函数必要我们自己进行重新,比如想通过比力日期类的指针进行日期的比力时,就必要将仿函数写成下面这个样子:
- #include <iostream>
- using namespace std;
- class DateLess
- {
- public:
- bool operator()(Date* p1, Date* p2)
- {
- return *p1 < *p2;
- }
- };
- //日期类参考上一个代码中的日期类
- int main()
- {
- Date d1(2024, 9, 10);
- Date d2(2024, 8, 15);
- Date* p1 = &d1;
- Date* p2 = &d2;
- DateLess func;
- cout << func(p1, p2) << endl;
- cout << func(p2, p1) << endl;
- return 0;
- }
复制代码
2.优先级队列priority_queue
2.1priority_queue的介绍
priority_queue的文档介绍
1.优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。priority_queue包含在queue这个头文件中。
2.雷同于堆,在堆中可以随时插入元素,而且只能检索最大堆元素(优先队列中位于顶部的元素)。在这内里(堆的介绍)中可以进行对堆的了解。
3.底层容器可以是任何标准容器类模板,也可以是其他特定计划的容器类。容器应该可以通过随机访问迭代器访问,并支持以下操纵:
(1)empty():检测容器是否为空。
(2)size():返回容器中有效元素个数。
(3)front():返回容器中第一个元素的引用。
(4)push_back():在容器尾部插入元素。
(5)pop_back():删除容器尾部元素。
4.标准容器vector和deque满意这些需求。默认情况下,假如没有为特定的epriority_queue类实例化指定容器类,则利用vector。
5.必要支持随机访问迭代器,以便始终在内部保持堆布局。容器适配器通过在必要时自动调用算法函数make_heap(),push_heap()和pop_heap()来自动完成操纵。
2.2priority_queue的利用
优先级队列默认利用vector作为其底层存储数据的容器,在vector上又利用dui算法将vector中元素构造成堆的布局,因此priority_queue就是堆,以是必要用到堆的位置,都可以考虑利用priority_queue。注意:默认情况下priority_queue是大堆。
- #include <iostream>
- #include <vector>
- #include <queue>
- #include <functional>
- using namespace std;
- void test_priority_queue()
- {
- // 默认情况下,创建的是大堆,其底层按照小于号比较
- vector<int> v{3, 2, 7, 6, 0, 4, 1, 9, 8, 5};
- priority_queue<int> q1;
- for (auto& e : v)
- q1.push(e);
- while(!q1.empty())
- {
- cout << q1.top() << " ";
- q1.pop();
- }
- }
- int main()
- {
- test_priority_queue();
- return 0;
- }
复制代码
假如每次访问顶部元素时都访问的是最小元素,则必要建立小堆。利用的时候只必要把上述priority_queue<int> q1 改为 priority_queue<int, vector<int>, greater<int>>即可,默认大堆的情况下,给的仿函数是less<int>。
2.3priority_queue的模拟实现
优先级队列的存储布局就是一个堆,内里的向上调解算法(AdjustUp())和向下调解算法(AdjustDown())参考堆的布局和实现。
- #pragma once
- #include <vector>
- 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;
- }
- };
- namespace XiaoC
- {
- //默认是大堆,排升序,用小于符号
- template<class T, class Container = vector<T>, class Compare = Less<T>>
- class priority_queue
- {
- public:
- void AdjustUp(int child)
- {
- Compare com;
- int parent = (child - 1) / 2;
- while (child > 0)
- {
- //if (_con[parent] < _con[child])
- if (com(_con[parent], _con[child]))
- {
- swap(_con[child], _con[parent]);
- child = parent;
- parent = (child - 1) / 2;
- }
- else
- {
- break;
- }
- }
- }
- void push(const T& x)
- {
- _con.push_back(x);
- AdjustUp(_con.size() - 1);
- }
- void AdjustDown(int parent)
- {
- // 先假设左孩子小
- int child = parent * 2 + 1;
- Compare com;
- while (child < _con.size()) // child >= n说明孩子不存在,调整到叶子了
- {
- // 找出小的那个孩子
- //if (child + 1 < _con.size() && _con[child] < _con[child + 1])
- if (child + 1 < _con.size() && com(_con[child], _con[child + 1]))
- {
- ++child;
- }
- //if (_con[parent] < _con[child])
- if (com(_con[parent], _con[child]))
- {
- swap(_con[child], _con[parent]);
- parent = child;
- child = parent * 2 + 1;
- }
- else
- {
- break;
- }
- }
- }
- void pop()
- {
- swap(_con[0], _con[_con.size() - 1]);
- _con.pop_back();
- AdjustDown(0);
- }
- const T& top() const
- {
- return _con[0];
- }
- size_t size() const
- {
- return _con.size();
- }
- bool empty() const
- {
- return _con.empty();
- }
- private:
- Container _con;
- };
- }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
|