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

CPP学习之priority_queue的使用及模拟实现

1. 介绍

priority_queue是一种容器适配器,内部元素按照升序或降序排列,因为是queue的一种,所以遵循先入先出原则(FIFO),底层数据结构采用堆,默认是大堆,底层数据容器默认采用vector,当然也可以采用其他支持随机访问(在常数时间O(1)内访问至任意位置的元素)的容器。

容器适配器是将特定的容器类封装成其底层容器类的容器。

适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该模式是将一个类的接口转换为客户希望的另一个接口。

2. 用法

priority_queue的常用接口:
在这里插入图片描述
使用举例:

#include <queue>
#include <functional> //greater或less算法的头文件void test_1()
{priority_queue<int, vector<int>, less<int>> pql; //less建大堆(降序),greater建小堆(升序)pql.push(3);pql.push(2);pql.push(5); pql.push(1);pql.push(9);//每次调整堆都是O(logN),因为N代表堆的元素个数,logN代表堆的层数int size = pql.size();for (int i = 0; i < size; i++){cout << pql.top() << " ";pql.pop();}cout << endl;
}

在创建priority_queue对象时,需要填写模板参数,这些模板参数都是类型。

如果插入的元素是自定义类型,那么就需要重载 < 或 > ;
比如下面的日期类

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;
};

3. 模拟实现

模拟实现代码如下:

my_priority_queue.h

#pragma once
#include<iostream>
#include<queue>
#include<vector>
#include<list>using namespace std;template<class T>
class my_less
{
public:bool operator()(const T& x, const T& y){return x < y;}
};template<class T>
class my_greater
{
public:bool operator()(const T& x, const T& y){return x > y;}
};template<class T, class container = vector<T>, class Compare = my_less<T>> //默认建大堆
class my_priority_queue
{
private:container _con;void adjust_down(int parent) //向下调整{Compare com;int child = parent * 2 + 1; //左孩子int size = _con.size();if (child < size - 1 && com(_con[child], _con[child + 1])) //如果左孩子小于右孩子,就用右孩子{child += 1;}while (child < size){if (com(_con[parent], _con[child])){swap(_con[parent], _con[child]);parent = child;child = parent * 2 + 1;}else{break;}}}void adjust_up(int child) //向上调整{Compare com;int parent = (child - 1) / 2;while (child > 0){if (com(_con[parent], _con[child])){swap(_con[parent], _con[child]);child = parent;parent = (child - 1) / 2;}else{break;}}}public:my_priority_queue(){}template<class input_iterator>my_priority_queue(input_iterator first, input_iterator last){while (first != last){_con.push_back(*first);++first;}for (int i = (_con.size() - 1 - 1) / 2; i >= 0; i--) //从最后一个叶子节点的父节点开始,向下调整{adjust_down(i);}}void push(const T& val){_con.push_back(val);adjust_up(_con.size() - 1); //尾部插入数据后,这个数据进行向上调整}void pop(){swap(_con[0], _con[_con.size() - 1]);_con.pop_back();adjust_down(0);}T& top(){return _con.front();}bool empty(){return _con.empty();}size_t size(){return _con.size();}
};
http://www.dtcms.com/a/343200.html

相关文章:

  • 3维模型导入到3Dmax中的修改色彩简单用法----第二讲
  • Kotlin 中适用集合数据的高阶函数(forEach、map、filter、groudBy、fold、sortedBy)
  • AI客服系统架构与实现:大模型、知识库与多轮对话的最佳实践
  • 蛋白质分析常用数据库2
  • QT开发---QT布局与QSS样式设置
  • 网络打印机自动化部署脚本
  • 工业机器人远程监控与运维物联网解决方案
  • 精准评估新纪元:AI得贤招聘官AI面试智能体6.3,重新定义AI面试
  • 赛灵思ZYNQ官方文档UG585自学翻译笔记与代码示例:Quad-SPl Flash 闪存控制器
  • 深度剖析字节跳动VeOmni框架
  • MySQL索引优化之索引条件字段类型不同
  • POI读和写
  • C2ComponentStore
  • CMOS知识点 MOS管线性区电流公式
  • Linux 网络命令大全
  • 在VSCode中配置.NET项目的tasks.json以实现清理、构建、热重载和发布等操作
  • vue2 watch 用法
  • K8s安全管理与持久化存储实战指南
  • Seaborn数据可视化实战:Seaborn入门-环境搭建与基础操作
  • Seaborn数据可视化实战
  • AI对口型唱演:科技赋能,开启虚拟歌者新篇章
  • 刷机维修进阶教程-----如何清除云账号 修复wifi 指南针 相机 指纹等刷机故障
  • 自然处理语言NLP:One-Hot编码、TF-IDF、词向量、NLP特征输入、EmbeddingLayer实现、word2vec
  • Linux 802.11协议栈深度分析与实践指南
  • 车机两分屏运行Unity制作的效果
  • OpenAI重新开源!gpt-oss-20b适配昇腾并上线魔乐社区
  • WebSocket连接的例子
  • 链游开发新篇章:融合区块链技术的游戏创新与探索
  • 什么是撮合引擎
  • 模型的量化-nf4和pf4