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

C++ priority_queue优先级队列

C++ priority_queue优先级队列(堆)

1. priority_queue的介绍和使用

1.1 queue的介绍

priority_queue的文档

priority_queue就是堆(优先级队列),分大根堆和小根堆

1.2 queue的使用

下面就介绍priority_queue的常用接口

1.2.1 成员函数
Member functions接口说明
empty判断priority_queue是否为空,是空返回true,非空返回false
size返回priority_queue中元素的个数
top返回priority_queue堆顶元素
push压堆,并且自动维护堆的性质(大根堆/小根堆)
pop删除priority_queue堆顶元素
swap交换两个priority_queue的内容
#include <iostream>
#include <queue>
using namespace std;
int main()
{priority_queue<int> heap1;	// 默认为大根堆priority_queue<int, vector<int>, less<int>>	heap2 = heap1;	// 大根堆priority_queue<int, vector<int>, greater<int>> heap3;		// 小根堆heap1.push(1);heap1.push(4);heap1.push(3);heap1.push(2);heap1.push(6);heap1.push(5);while (!heap1.empty()){cout << heap1.top() << endl;heap1.pop();}heap1.swap(heap2);return 0;
}

2. priority_queue底层实现

2.1 容器适配器(配接器)

在这里插入图片描述

根据文档说明 priority_queue 是一种 container adaptor 即适配器

2.1.1 什么是适配器(配接器)

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

C++STL中有三种适配器:

  1. container adapter 两个容器 stack 、queue其实是适配器
  2. iterator adapter
  3. function adapter 改变仿函数的接口者

2.2 仿函数

2.2.1 仿函数的定义

仿函数(Functor)是一种行为类似函数的对象,它可以被用作函数并接受参数。在C++中,仿函数通常是重载了函数调用运算符即 () operator()() ,仿函数可以像函数一样被调用,并且可以保存状态信息。

按照操作数划分:一元仿函数二元仿函数

按照功能划分:算数运算关系运算逻辑运算

2.2.2 仿函数的结构

下面就是一个典型的一个Less的仿函数(即前面比后面Less更小)

template<class T>
strcut Less
{bool operator()(const T& x, const T& y)	// ()运算符重载{return x < y;}
}

C++的 <functional> 文件中也有内置的仿函数 lessgreater

在这里插入图片描述

在这里插入图片描述

2.2.3 仿函数的使用

仿函数的功能类似函数指针,将仿函数作为参数传递给算法,并且满足STL对抽象性的要求(运用模板技术)。

方法一:

#include <iostream>
#include <algorithm>
using namespace std;
#include <vector>
int main()
{vector<int> v;srand(unsigned(time(0)));for (int i = 0; i < 10; ++i){v.push_back(rand() % 100);}sort(v.begin(), v.end(), less<int>());	// 传送less<int>()的匿名对象(升序)// sort(v.begin(), v.end(), greater<int>())	(降序)for (auto& e : v){cout << e << " ";}cout << endl;   return 0;
}

方法二:

int main()
{priority_queue<int, vector<int>, less<int>> heap;	// less<int>作为一种类型传给模板,大根堆//priority_queue<int, vector<int>, greater<int> heap;	// 小根堆heap.push(1);heap.push(4);heap.push(3);heap.push(2);heap.push(6);heap.push(5);while (!heap.empty()){cout << heap.top() << endl;heap.pop();}cout << endl;return 0;
}

2.3 模拟实现priority_queue

priority_queue.h

#pragma once#include <vector>template<class T>
struct Less
{// 重载运算符()bool operator()(const T& x, const T& y){return x < y;}
};template<class T>
struct Greater
{bool operator()(const T& x, const T& y)	{return x > y;}
};namespace Alen
{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 AdjustDown(int parent){Compare com;size_t child = parent * 2 + 1;size_t size = _con.size();while (child < size){// 找出比较大的孩子if (child + 1 < size && _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 push(const T& x){_con.push_back(x);AdjustUp(_con.size() - 1);}void pop(){swap(_con[0], _con[_con.size() - 1]);_con.pop_back();AdjustDown(0);}const T& top(){return _con[0];}size_t size() const{return _con.size();}bool empty() const{return _con.empty();}private:Container _con;};
}

这就是利用适配器的思想,调用已有的容器接口来完成客户期望的接口,并且采用引入了仿函数的用法,将大小根堆变化更加自由灵活,不需要更改原代码或者拷贝另一份。

http://www.dtcms.com/a/438021.html

相关文章:

  • Kafka 授权与 ACL 深入实践
  • 西宁市住房和城乡建设局网站做一个个人网站
  • 瑞安做网站多少钱东莞网站建设找谁
  • 谷歌云+Apache Airflow,数据处理自动化的强力武器
  • 小红书自动化运营:智能体+RPA自动化+MCP实现采集仿写和自动发布
  • 网站域名和网站网址建筑培训网 江苏
  • 定制开发开源AI智能名片S2B2C商城小程序的会员制运营研究——以“老铁用户”培养为核心目标
  • 【aigc】chrome-devtools-mcp怎么玩?
  • 从《Life of A Pixel》来看Chrome的渲染机制
  • 【项目实战 Day9】springboot + vue 苍穹外卖系统(用户端订单模块 + 商家端订单管理模块 完结)
  • Mac 安装Neo4j教程
  • blender 解决shift快捷键和中英切换重复的问题
  • 网站动态图怎么做阳明拍卖公司网站
  • 01_Docker 部署 Ollama 模型(支持 NVIDIA GPU)
  • 苏州新区网站制作wordpress视频格式
  • 一位Android用户的科技漫游手记
  • android中调用相册
  • 安卓基础组件031-Retrofit 网络请求框架
  • Redis 黑马点评-商户查询缓存
  • Android geckoview 集成,JS交互,官方demo
  • 【APK安全】Android 权限校验核心风险与防御指南
  • 单调队列与单调栈
  • 设计与优化Java API:构建高效、可维护的接口
  • Locality Sensitive Hashing (LSH) 详解:高效检测语言语句重复的利器
  • 阿里云网站开发零起步如何做设计师
  • 后端开发基础概念MVC以及Entity,DAO,DO,DTO,VO等概念
  • 七大排序算法的基本原理
  • Gateway-过滤器
  • 科普:Python 中,字典的“动态创建键”特性
  • Java 21 或 JavaFX 打包 exe 之 GraalVM Native Image 方案