【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.hqwc.cn/news/614823.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux第89步_了解异步通知及其结构和函数

1、了解“异步通知” “异步通知”的核心就是信号。信号是采用软件模拟的“中断”&#xff0c;它由“驱动程序”主动向“应用程序”发送信号&#xff0c;并报告自己可以访问了&#xff0c;“应用程序”收到信号以后&#xff0c;就从“驱动设备”中读取或者写入数据。整个过程就…

数字化用户投稿发表论文

《数字化用户》是由国家新闻出版总署批准的正规期刊。本刊坚持科学发展观&#xff0c;响应我国数字化信息时代的方针、政策和发展战略&#xff1b;探讨数字化建设的规划、方案和成果&#xff1b;交流数字化技术和应用的实例和经验&#xff1b;推广数字新技术、科技新理念&#…

C盘满了怎么办,清理工具TreeSize

TreeSize是一款强大的磁盘空间分析工具&#xff0c;它可以帮助用户轻松地找出电脑中占用空间最多的文件和程序&#xff0c;从而让用户进行针对性地删除或卸载。 占用空间很小 下载链接&#xff1a;https://pan.quark.cn/s/bea23ed6b1d3

电动车新国标迎来修订机会,用户的真实需求能被满足吗?

文&#xff5c;新熔财经 作者&#xff5c;宏一 自2019年4月《电动自行车安全技术规范》发布至今&#xff0c;电动车的新国标标准已经实施5年&#xff0c;市场上的争议也此起彼伏地持续了5年。 因为新国标对电动车的各项技术标准提出的明确要求&#xff0c;其中&#xff0c;最…

Docker 学习笔记(七):介绍 Dockerfile 相关知识,使用 Dockerfile 构建自己的 centos 镜像

一、前言 记录时间 [2024-4-12] 系列文章简摘&#xff1a; Docker学习笔记&#xff08;二&#xff09;&#xff1a;在Linux中部署Docker&#xff08;Centos7下安装docker、环境配置&#xff0c;以及镜像简单使用&#xff09; Docker 学习笔记&#xff08;三&#xff09;&#x…

MathJax —— Vue3的使用方法

版本&#xff1a; mathjax3 需要实现效果 一、使用方式 1. index.html 中引入 <!-- 识别单行&#xff0c;行内&#xff0c;\( \)样式的公式 --><script>MathJax {tex: {inlineMath: [[$, $],[$$, $$], [\\(, \\)]]},};</script><script id"MathJ…

使用vite从头搭建一个vue3项目(二)创建目录文件夹以及添加vue-router

目录 一、创建 vue3 项目 vite-vue3-project-js二、创建项目目录三、创建Home、About组件以及 vue-router 配置路由四、修改完成后页面 一、创建 vue3 项目 vite-vue3-project-js 使用 vite 创建一个极简 vue3 项目请参考此文章&#xff1a;使用Vite创建一个vue3项目 下面是我…

顺序表(增删减改)+通讯录项目(数据结构)

什么是顺序表 顺序表和数组的区别 顺序表本质就是数组 结构体初阶进阶 系统化的学习-CSDN博客 简单解释一下&#xff0c;就像大家去吃饭&#xff0c;然后左边是苍蝇馆子&#xff0c;右边是修饰过的苍蝇馆子&#xff0c;但是那个好看的苍蝇馆子一看&#xff0c;这不行啊&a…

使用SquareLine Studio创建LVGL项目到IMX6uLL平台

文章目录 前言一、SquareLine Studio是什么&#xff1f;二、下载安装三、工程配置四、交叉编译 前言 遇到的问题&#xff1a;#error LV_COLOR_DEPTH should be 16bit to match SquareLine Studios settings&#xff0c;解决方法见# 四、交叉编译 一、SquareLine Studio是什么…

GEE数据集——巴基斯坦国家级土壤侵蚀数据集(2005 年和 2015 年)

简介 巴基斯坦国家级土壤侵蚀数据集&#xff08;2005 年和 2015 年&#xff09; 该数据集采用修订的通用土壤流失方程 (RUSLE)&#xff0c;并考虑了六个关键影响因素&#xff1a;降雨侵蚀率 (R)、土壤可侵蚀性 (K)、坡长 (L)、坡陡 (S)、覆盖管理 (C) 和保护措施 (P)&#xff…

秋叶Stable diffusion的创世工具安装-带安装包链接

来自B站up秋葉aaaki&#xff0c;近期发布了Stable Diffusion整合包v4.7版本&#xff0c;一键在本地部署Stable Diffusion&#xff01;&#xff01; 适用于零基础想要使用AI绘画的小伙伴~本整合包支持SDXL&#xff0c;预装多种必须模型。无需安装git、python、cuda等任何内容&am…

面经:Presto/Trino高性能SQL查询引擎解析

作为一名专注于大数据技术的博主&#xff0c;我深知Presto&#xff08;现更名为Trino&#xff09;作为一款高性能SQL查询引擎&#xff0c;在现代数据栈中的重要地位。本文将结合我个人的面试经历&#xff0c;深入剖析Trino的核心特性和应用场景&#xff0c;分享面试必备知识点&…