当前位置: 首页 > news >正文

【c++】优先级队列|反向迭代器(vector|list)

优先级队列的常用函数的使用

#include<iostream>
#include<queue>
using namespace std;int main()
{priority_queue<int>st;st.push(1);st.push(7);st.push(5);st.push(2);st.push(3);st.push(9);while (!st.empty()){cout << st.top() << " ";st.pop();}
}

在这里插入图片描述


优先级队列的实现

优先级队列本质上是一个堆,所以实现和堆差不多,不同的是作为优先级队列我们可以使用别的容器来当适配器,比如说我们用vector作为优先级队列的容器,也可以用dequeue(双端队列)来做优先级队列的容器,
本篇我们使用vector来作为优先级队列的容器
所以我们优先级队列的函数可以用vector的函数来封装

#pragma once
#include<iostream>
#include<vector>
#include<functional>
using namespace std;
namespace bit{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;}};
template <class T, class Container = vector<T>, class Compare = less<T> >class priority_queue{public:priority_queue()=default;template <class InputIterator>priority_queue(InputIterator first, InputIterator last){while (first != last){push(*first);first++;}}void adjust_up(int child){int parent = (child - 1) / 2;while (child > 0){if (comp(c[child],c[parent])){swap(c[child],c[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}}void adjust_down(int parent){int child = parent * 2 + 1;while (child<c.size()){if (child + 1 < c.size() && comp(c[child + 1], c[child])){child = child + 1;}if (comp(c[child],c[parent])){swap(c[parent],c[child]);parent = child;child = parent * 2 + 1;}else{break;}}}bool empty() const{return c.empty();}size_t size() const{return c.size();}const T& top() const{return c[0];}void push(const T& x){    c.push_back(x);adjust_up(c.size() - 1);}void pop(){  swap(c[0], c[c.size() - 1]);c.pop_back();adjust_down(0);}private:Container c;Compare comp;};};
void test()
{bit::priority_queue<int, vector<int>, less<int>>st;st.push(4);st.push(7);st.push(3);st.push(1);st.push(5);st.push(2);while (!st.empty()){cout << st.top() << " ";st.pop();}}

优先级队列对自定义类型的排序

   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){_cout << d._year << "-" << d._month << "-" << d._day;return _cout;}private:int _year;int _month;int _day;};void test(){priority_queue<Date, vector<Date>, less<Date>>st;Date d1(2024, 4, 9);st.push(d1);st.push({2024,4,11});st.push(Date(2024, 4, 10));while (!st.empty()){cout << st.top() << " ";st.pop();}}

在这里插入图片描述
在这里插入图片描述
如果我们把地址放进优先级队列里面呢??

  void test(){priority_queue<Date*, vector<Date*>, less<Date*>> st;st.push(new Date(2018, 10, 29));st.push(new Date(2018, 10, 30));st.push(new Date(2018, 10, 28));while (!st.empty()){cout << *(st.top()) << endl;st.pop();}}

在这里插入图片描述
在这里插入图片描述
这里为什么排序是无序的呢??
因为它是按照地址的大小来排序的,但是每次new对象,他的地址大小是不确定的,所以排出来属无序的,我们可以实现一个仿函数来实现

   class  Dateless{public:bool operator()(const Date* x, const Date* y){return *x < *y;}};class  Dategreater{public:bool operator()(const Date* x, const Date* y){return *x > *y;}};

在这里插入图片描述


反向迭代器
首先迭代器是怎么将模版适配成所有类型的变量都可以使用??
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


反向迭代器的实现

#pragma onceusing namespace std;
namespace zjw
{     template<class  Iterator,class Ref,class Ptr>struct Reverselterator{typedef Reverselterator<Iterator, Ref, Ptr>Self;Iterator _it;Reverselterator(Iterator it):_it(it){}Ref operator*(){Iterator tmp = _it;return *(--tmp);}Ptr operator->(){return & (operator*());}Self& operator++(){--_it;return *this;}Self& operator--(){++_it;return *this;}bool operator!=(const Self& s){return _it != s._it;}};
}

根据反向迭代器的特性,我们知道正向迭代器的++就是反向迭代器的–,正向迭代器的–就是反向迭代器的++,实现下面两个函数

	Self& operator++(){--_it;return *this;}Self& operator--(){++_it;return *this;}
	Ref operator*(){Iterator tmp = _it;return *(--tmp);}

这个为什么要先–呢?
在这里插入图片描述
在这里插入图片描述
同时,需要在vector类或者list类中添加反向迭代器记录起始位置和结束位置的函数

  reverse_iterator rbegin(){//return reverse_iterator(end());return iterator(end());}reverse_iterator rend(){// return reverse_iterator(begin());return iterator(begin());}

这样写比较好理解,用正向迭代器的begin()做反向迭代器的rend(),用正向迭代器的end()做反向迭代器的rbegin(),

vector迭代器的重命名

         typedef T* iterator;typedef const T* const_iterator;typedef Reverselterator<iterator,T&,T*> reverse_iterator;typedef Reverselterator<const_iterator,const T&,const T*> const_reverse_iterator;

list迭代器的重命名

        typedef ListIterator<T, T&, T*> iterator;typedef ListIterator<T, const T&,const T*> const_iterator;typedef Reverselterator<iterator,T&,T*> reverse_iterator;typedef Reverselterator<const_iterator,const T&,const T*> const_reverse_iterator;

不同的是vector迭代器使用的是原生指针,这样写反向迭代器的好处是既可以给list使用,也可以给vector使用
注意反向迭代器的类命名空间必须和vector或list的命名空间一样.

测试vector的反向迭代器
在这里插入图片描述
测试list的反向迭代器
在这里插入图片描述


http://www.lryc.cn/news/337880.html

相关文章:

  • gocron定时任务管理
  • JCYZ H3CNE-RS+
  • 太阳光光照试验耐久性老化试验使用太阳光模拟器系统
  • Centos 7.9.2009 下 Gitlab 完全卸载
  • Navicat Premium 16 for Mac/Win:数据库管理的全能之选
  • 使用腾讯云服务器如何搭建网站?新手建站教程
  • 抖音快手直播整蛊软件插件工具合集(多啦咪/梦歌)
  • 探究C++20协程(2)——取值、传值、销毁与序列生成器实现
  • 【前端面试3+1】12 toktn验证过程、面向对象特性、webpack和vite的区别、【字符串中的第一个唯一字符】
  • 机器人瓶胚检测工作站(H3U脉冲轴控制)
  • 数字货币:未来金融的崭新篇章
  • USACO18DEC部分题 补题报告
  • 聊一聊一些关于npm、pnpm、yarn的事
  • c语言多功能计算软件170
  • python图形化展示数据:保存为图片后查看
  • PostgreSQL入门到实战-第二十四弹
  • Spring Boot 统一功能处理(二)
  • Flutter开发基础之动画专题
  • PHP 图片裁剪类封装
  • Android 14.0 SystemUI修改状态栏电池图标样式为横屏显示
  • FPGA:图像数字细节增强算法(工程+仿真+实物,可用毕设)
  • Android netty的使用
  • 苹果电脑启动磁盘是什么意思 苹果电脑磁盘清理软件 mac找不到启动磁盘 启动磁盘没有足够的空间来进行分区
  • 【Java SE】多态
  • Yarn vs npm的大同小异Yarn是什么?
  • 1.Godot引擎|场景|节点|GDS|介绍
  • springboot3 redis 实现分布式锁
  • 2024年第十四届MathorCup数学应用挑战赛A题思路分享(妈妈杯)
  • 运动听歌哪款耳机靠谱?精选五款热门开放式耳机
  • Kubernetes学习笔记12