c++11 标准模板(STL)(std::priority_queue)(四)

news2024/9/19 10:53:51
适配一个容器以提供优先级队列
std::priority_queue
定义于头文件 <queue>
template<

    class T,
    class Container = std::vector<T>,
    class Compare = std::less<typename Container::value_type>

> class priority_queue;

priority_queue 是容器适配器,它提供常数时间的(默认)最大元素查找,对数代价的插入与释出。

可用用户提供的 Compare 更改顺序,例如,用 std::greater<T> 将导致最小元素作为 top() 出现。

priority_queue 工作类似管理某些随机访问容器中的堆,优势是不可能突然把堆非法化。

模板形参

T-存储的元素类型。若 TContainer::value_type 不是同一类型则行为未定义。 (C++17 起)
Container-用于存储元素的底层容器类型。容器必须满足序列容器 (SequenceContainer) 的要求,而其迭代器必须满足遗留随机访问迭代器 (LegacyRandomAccessIterator) 的要求。另外,它必须提供拥有通常语义的下列函数:
  • front()
  • push_back()
  • pop_back()

标准容器 std::vector 和 std::deque 满足这些要求。

Compare-提供严格弱序的比较 (Compare) 类型。

注意 比较 (Compare) 形参的定义,使得若其第一参数在弱序中先于其第二参数则返回 true 。但因为 priority_queue 首先输出最大元素,故“先来”的元素实际上最后输出。即队列头含有按照 比较 (Compare) 所施加弱序的“最后”元素。

元素访问

访问栈顶元素

std::priority_queue<T,Container,Compare>::top

const_reference top() const;

返回到 priority_queue 顶元素的引用。此元素将在调用 pop() 时被移除。若使用默认比较函数,则返回的元素亦为优先队列中最大的元素。

参数

(无)

返回值

到顶元素的引用,如同以调用 c.front() 获得。

复杂度

常数。

修改器

插入元素,并对底层容器排序

std::priority_queue<T,Container,Compare>::push

void push( const value_type& value );

void push( value_type&& value );

(C++11 起)

 推给定的元素 value 到 priority_queue 中。

1) 等效地调用 c.push_back(value); std::push_heap(c.begin(), c.end(), comp);

2) 等效地调用 c.push_back(std::move(value)); std::push_heap(c.begin(), c.end(), comp);

参数

value-要推入的元素值

返回值

(无)

复杂度

对数次比较加 Container::push_back 的复杂度。

删除栈顶元素

std::priority_queue<T,Container,Compare>::pop

void pop();

从 priority_queue 移除顶元素。等效地调用 std::pop_heap(c.begin(), c.end(), comp); c.pop_back(); 。

参数

(无)

返回值

(无)

复杂度

对数次比较加 Container::pop_back 的复杂度。

交换内容

std::priority_queue<T,Container,Compare>::swap

void swap( priority_queue& other ) noexcept(/* see below */);

(C++11 起)

交换容器适配器与 other 的内容。等效地调用 using std::swap; swap(c, other.c); swap(comp, other.comp); 。

参数

other-要交换内容的容器适配器

返回值

(无)

示例

noexcept 规定:  

noexcept(noexcept(swap(c, other.c)) && noexcept(swap(comp, other.comp)))

上述表达式中,用与 C++17 std::is_nothrow_swappable 特性所用的相同方式查找标识符 swap

(C++17 前)
noexcept 规定:  

noexcept(std::is_nothrow_swappable<Container>::value && std::is_nothrow_swappable<Compare>::value)

(C++17 起)

复杂度

与底层容器相同(典型地为常数)。

调用示例

#include <iostream>
#include <forward_list>
#include <string>
#include <iterator>
#include <algorithm>
#include <functional>
#include <queue>
#include <deque>
#include <time.h>

using namespace std;

struct Cell
{
    int x;
    int y;

    Cell() = default;
    Cell(int a, int b): x(a), y(b) {}

    Cell &operator +=(const Cell &cell)
    {
        x += cell.x;
        y += cell.y;
        return *this;
    }

    Cell &operator +(const Cell &cell)
    {
        x += cell.x;
        y += cell.y;
        return *this;
    }

    Cell &operator *(const Cell &cell)
    {
        x *= cell.x;
        y *= cell.y;
        return *this;
    }

    Cell &operator ++()
    {
        x += 1;
        y += 1;
        return *this;
    }


    bool operator <(const Cell &cell) const
    {
        if (x == cell.x)
        {
            return y < cell.y;
        }
        else
        {
            return x < cell.x;
        }
    }

    bool operator >(const Cell &cell) const
    {
        if (x == cell.x)
        {
            return y > cell.y;
        }
        else
        {
            return x > cell.x;
        }
    }

    bool operator ==(const Cell &cell) const
    {
        return x == cell.x && y == cell.y;
    }
};

std::ostream &operator<<(std::ostream &os, const Cell &cell)
{
    os << "{" << cell.x << "," << cell.y << "}";
    return os;
}

template<typename _Tp, typename _Sequence = vector<_Tp>,
         typename _Compare  = less<typename _Sequence::value_type> >
void queuePrint(const std::string &name,
                const std::priority_queue<_Tp, vector<_Tp>, _Compare> &queue)
{
    std::cout << name ;
    std::priority_queue<_Tp, vector<_Tp>, _Compare> queuep = queue;
    while (queuep.size() > 0)
    {
        std::cout << queuep.top() << " ";
        queuep.pop();
    }
    std::cout << std::endl;
}

struct Compare
{
    Compare() {}
    bool operator()(const Cell &a, const Cell &b)const
    {
        if (a.x == b.x)
        {
            return a.y < b.y;
        }
        return a.x < b.x;
    }
};

int main()
{
    std::cout << std::boolalpha;

    std::mt19937 g{std::random_device{}()};
    srand((unsigned)time(NULL));

    auto generate = []()
    {
        int n = std::rand() % 10 + 110;
        Cell cell{n, n};
        return cell;
    };

    std::vector<Cell> vector1(6);
    std::generate(vector1.begin(), vector1.end(), generate);
    std::cout << "vector1:  ";
    std::copy(vector1.begin(), vector1.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;

    //2) 以 cont 的内容复制构造底层容器 c 。
    std::priority_queue<Cell> queue1(std::less<Cell>(), vector1);

    while (!queue1.empty())
    {
        //返回到 priority_queue 顶元素的引用。
        //此元素将在调用 pop() 时被移除。
        //若使用默认比较函数,则返回的元素亦为优先队列中最大的元素。
        //const_reference
        std::cout << "queue1.front() before: " << queue1.top() << " ";
        //从 queue 移除顶元素。等效地调用 c.pop_back()
        queue1.pop();
        std::cout << std::endl;
    }
    std::cout << std::endl;

    std::priority_queue<Cell> queue2;
    int index = 0;
    while (index < 6)
    {
        Cell cell = generate();
        if (queue2.size() % 2 == 0)
        {
            //推给定的元素 value 到 queue 尾。
            //1) 等效地调用 c.push_back(value)
            queue2.push(cell);
        }
        else
        {
            //推给定的元素 value 到 queue 尾。
            //2) 等效地调用 c.push_back(std::move(value)),移动语义
            queue2.push(std::move(cell));
        }
        std::cout << "queue2.top() : " << queue2.top() ;
        queue2.pop();
        std::cout << std::endl;
        index++;
    }
    std::cout << std::endl;

    std::priority_queue<Cell> queue3;
    index = 0;
    while (index < 6)
    {
        int n = std::rand() % 10 + 110;
        //推入新元素到 queue 结尾。原位构造元素,即不进行移动或复制操作。
        //以与提供给函数者准确相同的参数调用元素的构造函数。
        //等效地调用 c.emplace_back(std::forward<Args>(args)...);
        queue3.emplace(n, n);
        std::cout << "queue3.front() : " << queue3.top() ;
        std::cout << std::endl;
        queue3.pop();
        index++;
    }
    std::cout << std::endl;

    std::vector<Cell> vector2(6);
    std::generate(vector2.begin(), vector2.end(), generate);
    std::cout << "vector2:  ";
    std::copy(vector2.begin(), vector2.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;
    std::vector<Cell> vector3(6);
    std::generate(vector3.begin(), vector3.end(), generate);
    std::cout << "vector3:  ";
    std::copy(vector3.begin(), vector3.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;
    std::cout << std::endl;

    std::priority_queue<Cell> queue4(std::less<Cell>(), vector2);
    std::priority_queue<Cell> queue5(std::less<Cell>(), vector3);
    std::cout << "swap before:  " << std::endl;
    queuePrint("queue4:   ", queue4);
    queuePrint("queue5:   ", queue5);
    //交换容器适配器与 other 的内容。
    //等效地调用 using std::swap; swap(c, other.c);
    queue4.swap(queue5);
    std::cout << "swap after:  " << std::endl;
    queuePrint("queue4:   ", queue4);
    queuePrint("queue5:   ", queue5);

    return 0;
}

输出

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/458827.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mysql 查询同类数据中某一数字最大的所有数据

方法一、将时间进行排序后再分组 该表表名为customer, park_id表示园区id&#xff0c;joined_at表示用户的加入时间&#xff0c;created_at表示用户的创建时间。 需求&#xff1a;查出每个园区中&#xff0c;最早加入园区的第一位用户 select * from (select * from custome…

outlook手动配置保姆级别教学

outlook保姆级教学 hello&#xff0c;各位小伙伴&#xff0c;今天呢讲一下outlook的配置&#xff0c;相信啊再次之前也必然看到过其他博主写的&#xff0c;我呢也是前段时间有需求但是网上总是零零散散的。 我呢配置过qq 和126的邮箱这里呢开始教程. 第一步呢首先点击账户的设…

每日一个小技巧:1招教你wav格式如何转换mp3

wav是一种质量较高的音频格式&#xff0c;但它的文件大小通常比较大。为了更方便地分享和存储音频文件&#xff0c;许多人都会选择将其转换为mp3格式。因为mp3格式能够在保持较高音质的同时&#xff0c;尽量降低文件大小&#xff0c;帮助你节省许多磁盘空间。那你们知道wav格式…

Python每日一练(20230425)

目录 1. 多数元素 &#x1f31f; 2. 二叉树的层序遍历 II &#x1f31f;&#x1f31f; 3. 最接近的三数之和 &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专…

欧几里得算法、扩展欧几里得算法(特解、应用、通解)

文章目录 1. 欧几里得算法&#xff08;也叫辗转相除法&#xff09;1.1 直接上模拟1.2 几何理解1.3 用代数方法证明 g c d ( a , b ) g c d ( b , a % b ) gcd(a, b) gcd(b, a \% b) gcd(a,b)gcd(b,a%b)1.3.1 左推右&#xff1a; g c d ( a , b ) g c d ( b , a % b ) gcd(a…

Vue 3 第十五章:组件五(内置组件-keep-alive)

文章目录 1. keep-alive1.1. 基本用法1.2. 包含/排除1.3. 最大缓存实例数1.4. <keepAlive> 组件的生命周期 1. keep-alive <keep-alive>组件用于缓存动态组件的实例&#xff0c;以便在它们被切换时保持状态。例如&#xff0c;当我们在一个选项卡中切换不同的视图…

Unity Camera -- (2)相机投影设置

在Editor中调整相机 和场景视图中的其他游戏物体一样&#xff0c;相机本身也可以通过使用移动和旋转工具来进行调整。但这种方式比较难用&#xff0c;调整起来又慢又不精确。我们可以使用Move To View功能来快速调整相机所拍摄的画面。 1. 打开Camera_Projection_Scene&#xf…

Java 版企业工程项目管理系统平台(三控:进度组织、质量安全、预算资金成本、二平台:招采、设计管理)

工程项目管理软件&#xff08;工程项目管理系统&#xff09;对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营&#xff0c;全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#…

7、如何使用接口?

1、基本用法 我们需要定义这样一个函数&#xff0c;参数是一个对象&#xff0c;里面包含两个字段&#xff1a;firstName 和 lastName&#xff0c;也就是英文的名和姓&#xff0c;然后返回一个拼接后的完整名字。来看下函数的定义&#xff1a; // 注&#xff1a;这段代码为纯Ja…

【致敬未来的攻城狮计划】— 连续打卡第十二天:FSP固件库开发按键输入检测控制LED灯闪烁。

系列文章目录 1.连续打卡第一天&#xff1a;提前对CPK_RA2E1是瑞萨RA系列开发板的初体验&#xff0c;了解一下 2.开发环境的选择和调试&#xff08;从零开始&#xff0c;加油&#xff09; 3.欲速则不达&#xff0c;今天是对RA2E1 基础知识的补充学习。 4.e2 studio 使用教程 5.…

关于 OpenShift(OKD) 网络 Service、Routes的一些笔记

写在前面 参加考试&#xff0c;分享一些学习 OpenShift 的笔记博文内容为 OpenShift 网络相关组件 Service、Routes 很浅的一些认识学习环境为 openshift v3 的版本&#xff0c;有些旧这里如果专门学习 openshift &#xff0c;建议学习 v4 版本理解不足小伙伴帮忙指正 傍晚时分…

轻量级服务器nginx:反向代理的具体配置

系列文章目录 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 反向代理和负载均衡 系列文章目录一 反向代理1.正向代理2.反向代理 二 反向代理的实际部署1.配置tomcat2.配置host&#xff0c;nginx反向代理的配置三 结果展示四 总结 一 反向代理 1.正向代理 我们…

通过docker发布项目

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言例如&#xff1a;docker项目的发布方式 [docker发布的参考链接](https://www.cnblogs.com/emperorking/articles/11244253.html) 一、docker是什么&#xff1f;…

Django框架之自定义管理页面

Django框架Admin站点管理一些默认的显示和功能包括语言都可以自定义设置处理&#xff0c;以贴近我们的实际业务。 属性说明 列表页属性 配置文件myapp/admin.py from django.contrib import admin from .models import Grades, Students# Register your models here.# 注册班…

收废品小程序开发中的常见问题及解决方法

常见问题 1. 用户界面设计 小程序的用户界面设计至关重要。设计师需要在用户界面中提供清晰的指示&#xff0c;以便用户可以轻松地找到他们需要的功能。同时&#xff0c;设计师还需要确保用户界面的整体风格与公司的品牌形象相符。 2. 功能开发 开发小程序的功能需要考虑到…

深入学习RabbitMQ五种模式(一)

1.安装erlang 下载otp_win64_25.3.exe https://www.erlang.org/downloads erlang安装完成&#xff0c;需要配置erlang环境变量 ERLANG_HOMEE:\software\Erlang OTPPATH%PATH%;%ERLANG_HOME%\bin; 2.安装RabbitMQ 下载rabbitmq-server-3.11.13.exe https://www.rabbitmq.com/dow…

交叉验证之KFold和StratifiedKFold的使用(附案例实战)

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

力扣---LeetCode88. 合并两个有序数组

文章目录 前言88. 合并两个有序数组链接&#xff1a;方法一&#xff1a;三指针(后插)1.2 代码&#xff1a;1.2 流程图&#xff1a;方法二&#xff1a;开辟新空间2.1 代码&#xff1a;2.2 流程图&#xff1a;2.3 注意&#xff1a; 总结 前言 “或许你并不熠熠生辉甚至有点木讷但…

POSTGRESQL COPY 命令原理与加速数据 导入提高速度200%以上

开头还是介绍一下群&#xff0c;如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;在新加的朋友会分到2群&#xff08;共…

vue2+vue3——107+

vue2vue3——107 vue2 Vuex工作原理图【23:54】vue2 搭建Vuex环境【26:40】插入 话题npm i vue3 store / index.js修改 vue2 求和案例_vuex版【22:39】vue2 vuex开发者工具的使用【23:21】vue2 getters配置项【07:55】vue2 mapState与mapGetters【25:20】vue2 mapActions与mapM…