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

news2024/9/21 4:40:08
适配一个容器以提供优先级队列
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) 所施加弱序的“最后”元素。

成员函数

构造 priority_queue

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

priority_queue() : priority_queue(Compare(), Container()) { }

(1)(C++11 起)

explicit priority_queue(const Compare& compare)
    : priority_queue(compare, Container()) { }

(2)(C++11 起)

explicit priority_queue( const Compare& compare = Compare(),
                         const Container& cont = Container() );

(3)(C++11 前)

priority_queue( const Compare& compare, const Container& cont );

(C++11 起)

priority_queue( const Compare& compare, Container&& cont );

(4)(C++11 起)

priority_queue( const priority_queue& other );

(5)

priority_queue( priority_queue&& other );

(6)(C++11 起)

template< class Alloc >
explicit priority_queue( const Alloc& alloc );

(7)(C++11 起)

template< class Alloc >
priority_queue( const Compare& compare, const Alloc& alloc );

(8)(C++11 起)
template< class Alloc >

priority_queue( const Compare& compare, const Container& cont,

                const Alloc& alloc );
(9)(C++11 起)
template< class Alloc >

priority_queue( const Compare& compare, Container&& cont,

                const Alloc& alloc );
(10)(C++11 起)

template< class Alloc >
priority_queue( const priority_queue& other, const Alloc& alloc );

(11)(C++11 起)

template< class Alloc >
priority_queue( priority_queue&& other, const Alloc& alloc );

(12)(C++11 起)
template< class InputIt >

priority_queue( InputIt first, InputIt last,

                const Compare& compare, const Container& cont );
(13)(C++11 起)
template< class InputIt >

priority_queue( InputIt first, InputIt last,
                const Compare& compare = Compare(),

                Container&& cont = Container() );
(14)(C++11 起)

 

从多种数据源构造容器适配器的底层容器。

1) 默认构造函数。值初始化底层容器。

2) 用 compare 的内容复制构造比较函数对象 comp 。值初始化底层容器 c

3) 用 cont 的内容复制构造底层容器 c 。用 compare 的内容复制构造比较函数对象 comp 。调用 std::make_heap(c.begin(), c.end(), comp) 。此亦为默认构造函数。 (C++11 前)

4) 用 std::move(cont) 移动构造底层容器 c 。以 compare 的内容复制构造比较函数对象 comp 。调用 std::make_heap(c.begin(), c.end(), comp) 。

5) 复制构造函数。以 other.c 的内容复制构造底层容器。以 other.comp 复制构造比较函数对象。 (隐式声明)

6) 移动构造函数。以 std::move(other.c) 构造底层容器。以 std::move(other.comp) 构造比较函数对象。 (隐式声明)

7-12) 仅若 std::uses_allocator<container_type, Alloc>::value == true ,即若底层容器是具分配器容器(对所有标准库容器为真),才定义下列构造函数。

7) 以 alloc 为分配器构造底层容器。等效地调用 c(alloc) 。值初始化 comp

8) 以 alloc 为分配器构造底层容器。等效地调用 c(alloc) 。从 compare 复制构造 comp

9) 用 cont 的内容,以 alloc 为分配器构造底层容器,如同用 c(cont, alloc) 。从 compare 复制构造 comp 。然后调用 std::make_heap(c.begin(), c.end(), comp) 。

10) 用 cont 的内容,以 alloc 为分配器并以移动语义构造底层容器,如同用 c(std::move(cont), alloc) 。从 compare 复制构造 comp 。然后调用 std::make_heap(c.begin(), c.end(), comp) 。

11) 用 other.c 的内容,以 alloc 为分配器构造底层容器。等效地调用 c(other.c, alloc) 。从 other.comp 复制构造 comp

12) 用 other 的内容,同时以 alloc 为分配器构造适配器。等效地调用 c(std::move(other.c), alloc) 。从 other.comp 移动构造 comp

13) 从 cont 复制构造 c 并从 compare 复制构造 comp 。然后调用 c.insert(c.end(), first, last); ,再调用 std::make_heap(c.begin(), c.end(), comp); 。

14) 从 std::move(cont) 移动构造 c 并从 std::move(compare) 移动构造 comp 。然后调用 c.insert(c.end(), first, last); ,再调用 std::make_heap(c.begin(), c.end(), comp); 。

参数

alloc-用于底层容器所有内存分配的分配器
other-用作源初始化底层容器的另一容器适配器
cont-用作源初始化底层容器的容器
compare-用于初始化底层比较函数对象的比较函数对象
first, last-要初始化的元素范围
类型要求
- Alloc 必须满足分配器 (Allocator) 的要求。
- Container 必须满足容器 (Container) 的要求。仅若 Container 满足具分配器容器 (AllocatorAwareContainer) 的要求才定义构造函数 (5-10)
- InputIt 必须满足遗留输入迭代器 (LegacyInputIterator) 的要求。

复杂度

1-2) 常数。

3,5) O(N) 次比较,其中 N 为 cont.size() 。

另外,调用 O(N) 次 value_type 的构造函数,其中 N 为 cont.size() 。

4) O(N) 次比较,其中 N 为 cont.size() 。

6-8) 常数。

9) O(N) 次比较,其中 N 为 cont.size() 。

另外,调用 O(N) 次 value_type 的构造函数,其中 N 为 cont.size() 。

10) O(N) 次比较,其中 N 为 cont.size() 。

11) 与 other 的大小成线性。

12) 常数。

13) O(N) 次比较,其中 N 为 cont.size() + std::distance(first, last) 。

另外,调用 O(N) 次 value_type 的构造函数,其中 N 为 cont.size() 。

14) O(N) 次比较,其中 N 为 cont.size() + std::distance(first, last) 。

析构 priority_queue

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

~priority_queue();

销毁容器适配器。调用元素的析构函数,然后解分配所用的存储。注意,若元素是指针,则不销毁所指向的对象。

复杂度

与容器适配器大小成线性。

调用示例

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

    //1) 默认构造函数。值初始化底层容器。
    std::priority_queue<Cell> queue1;
    std::cout << "queue1 empty: " << queue1.empty() << std::endl;

    std::priority_queue<Cell, std::vector<Cell>, Compare> queue3;
    std::cout << "queue3 empty: " << queue3.empty() << std::endl;
    std::cout << std::endl;

    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) 用 compare 的内容复制构造比较函数对象 comp 。值初始化底层容器 c 。
    std::priority_queue<Cell> queue2(std::less<Cell>(), vector1);
    queuePrint("queue2:   ", queue2);
    std::cout << std::endl;

    //4) 用 std::move(cont) 移动构造底层容器 c 。
    //以 compare 的内容复制构造比较函数对象 comp 。
    //调用 std::make_heap(c.begin(), c.end(), comp) 。
    std::priority_queue<Cell> queue4(std::less<Cell>(), std::move(vector1));
    queuePrint("queue4:   ", queue4);
    std::cout << std::endl;

    //5) 复制构造函数。以 other.c 的内容复制构造底层容器。以 other.comp 复制构造比较函数对象。
    std::priority_queue<Cell> queue5(queue2);
    queuePrint("queue5:   ", queue5);
    std::cout << std::endl;

    //6) 移动构造函数。以 std::move(other.c) 构造底层容器。
    //以 std::move(other.comp) 构造比较函数对象。
    std::priority_queue<Cell> queue6(std::move(queue2));
    queuePrint("queue6:   ", queue6);
    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;
    //13) 从 cont 复制构造 c 并从 compare 复制构造 comp 。
    //然后调用 c.insert(c.end(), first, last);
    //再调用 std::make_heap(c.begin(), c.end(), comp);
    std::priority_queue<Cell> queue7(vector2.begin(), vector2.end());
    queuePrint("queue7:   ", queue7);
    std::cout << std::endl;

    return 0;
}

输出

 

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

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

相关文章

Windows下编译UHD

1.安装Visual Studio 2019,下载地址https://download.csdn.net/download/qq_36314864/87719209 2.安装cmake,下载地址https://download.csdn.net/download/qq_36314864/87719747 安装完成后记得C:\Program Files\cmake-3.22.1-windows-x86_64\bin添加到环境变量里面,或者安…

数据结构修炼:链表习题讲解!!!

题一&#xff1a;移除链表元素 我们可以看出这道题是让我们删除特定数据&#xff0c;我们可以用双指针来解这道题&#xff1a; 如果首元素为val&#xff0c;那么cur和head一起后移&#xff1a; 如果没有碰到val&#xff0c;那么就会cur后移&#xff0c;并且提前将cur传给perv&a…

如何避免美国ASP主机服务器崩溃和故障?

在当今数字化时代&#xff0c;网站是一个公司展示其业务的主要方式之一。因此&#xff0c;公司的在线业务应该始终保持高可用性和可靠性。ASP主机服务器是一种用于托管网站的服务器&#xff0c;其特点是可靠性高。但是&#xff0c;即使是最可靠的服务器也会遭受故障或崩溃。在本…

漏刻有时数据可视化大屏引导页设计(php原生开发、主背景图片更换、标题设置)

文章目录 1.引入外部js库2.HTML排版3.项目配置文件4.菜单图标自动匹配5.php与html混排6.CSS样式表7.添加/编辑信息8.生成配置文件 在制作数据可视化大屏时&#xff0c;尤其是在触摸屏演示时&#xff0c;需要开发和设计对应的数据大屏引导页。基于常见场景&#xff0c;单独开发数…

Unity API详解——Object类

Object类是Unity中所有对象的基类&#xff0c;例如GameObject、Component、Material、Shader、Texture、Mesh、Font等都是Object的子类。本博客介绍Object类的一些实例方法和静态方法。 一、Object类实例方法 在Object类中&#xff0c;涉及的实例方法主要有GetInstanceID方法…

Java基础学习(10)

Java基础学习 一、JDK8时间类1.1 Zoneld时区1.2 Instant时间戳1.3 ZonedDateTime1.4 DateTimeFormatter1.5 日历类时间表示1.6 工具类1.7 包装类JDK5提出的新特性Integer成员方法 二、集合进阶2.1 集合的体系结构2.1.1 Collection 2.2collection的遍历方式2.2.1 迭代器遍历2.2.…

RecycleView与TabLayout联动展示更多功能列表页面的实现

一.前言 对于更多功能页面&#xff0c;使用RecycleView与TabLayout联动方式实现是比较常见的&#xff0c;先上效果图&#xff08;请大佬们忽略gif的水印&#xff09; 单独使用TabLayout和RecycleView都是比较容易的&#xff0c;这里就不做举例了&#xff1b;gif中的列表实际上…

权限控制导入到项目中

在项目中应用 进行认证和授权需要前面课程中提到的权限模型涉及的7张表支撑&#xff0c;因为用户信息、权限信息、菜单信息、角色信息、关联信息等都保存在这7张表中&#xff0c;也就是这些表中的数据是进行认证和授权的依据。所以在真正进行认证和授权之前需要对这些数据进行…

( “树” 之 BST) 501. 二叉搜索树中的众数 ——【Leetcode每日一题】

二叉查找树&#xff08;BST&#xff09;&#xff1a;根节点大于等于左子树所有节点&#xff0c;小于等于右子树所有节点。 二叉查找树中序遍历有序。 ❓501. 二叉搜索树中的众数 难度&#xff1a;简单 给你一个含重复值的二叉搜索树&#xff08;BST&#xff09;的根节点 root…

Leetcode每日一题——“合并两个有序数组”

各位CSDN的uu们你们好呀&#xff0c;又到小雅兰的愉快题解时候啦&#xff0c;今天&#xff0c;我们的题目内容是合并两个有序数组&#xff0c;下面&#xff0c;让我们进入合并两个有序数组的世界吧 示例 1&#xff1a; 输入&#xff1a;nums1 [1,2,3,0,0,0], m 3, nums2 [2,…

C++内联/构造函数详解

内联函数 宏&#xff1a; 宏的优缺点&#xff1f; 优点&#xff1a; 1.增强代码的复用性。 2.提高性能。 缺点&#xff1a; 1.展开后会使得代码长度变长&#xff0c;使可执行程序变大 2.不方便调试宏。&#xff08;因为预编译阶段进行了替换&#xff09; 3.导致代码可读性差…

Python 查看数据常用函数

Python 查看数据常用函数&#xff08;以 iris 数据集为例&#xff09; 1、查看前后几行数据&#xff1a;head 和 tail2、查看数据基本信息&#xff1a;info3、查看数据统计信息&#xff1a;describe 查看数据可以用很多函数&#xff0c;这里就挑选几个最常用的进行简单展示&…

SpringBoot自动配置原理、手写一个xxx-spring-boot-starter

SpringBoot的自动配置是&#xff1a;当项目中使用了一个第三方依赖&#xff0c;如何将第三方依赖中的Bean加载到Spring的IOC容器中&#xff0c;我们就可以做到无需额外的配置&#xff0c;直接使用第三方jar中的Bean。 SpringBoot的理念是“约定大于配置”&#xff0c;只要按照S…

【下载器篇】IDM下载记录分析(简)

【下载器篇】IDM下载记录分析&#xff08;简&#xff09; IDM下载记录分析-未完待续—【蘇小沐】 文章目录 【下载器篇】IDM下载记录分析&#xff08;简&#xff09;1.实验环境 &#xff08;一&#xff09;IDM下载记录分析-未完待续临时文件夹下载痕迹 总结 1.实验环境 系统版…

【内网渗透】春秋云镜Intitle WP

前言 第一次正式接触内网渗透的东西&#xff0c;写的很新手&#xff0c;也适合新手观看&#xff0c;有问题可以私信或评论&#xff0c;接下来会持续更新 信息收集 拿到地址先nmap扫端口 没什么发现&#xff0c;直接访问80端口&#xff0c;看到图标知道是thinkphp 第一台Th…

leetcode刷题(8)二叉树(2)

各位朋友们&#xff0c;大家好&#xff01;今天我为大家分享的是关于二叉树leetcode刷题的第二篇&#xff0c;我们一起来看看吧。 文章目录 1.对称二叉树题目要求示例做题思路代码实现 2.二叉树的最大深度题目要求示例做题思路代码实现 3.翻转二叉树题目要求示例做题思路代码实…

WebSocket入门

WebSocket 1.1websoket介绍 websocket是一种网络通信协议&#xff0c;RFC6455定义了它的通信标准 websocket是Html5开始提供的一种在单个TCP连接上进行全双工通讯的协议 Http协议是一种无状态、无连接、单向的应用层协议&#xff0c;它采用了请求/响应模型&#xff0c;通信…

Tomcat多实例部署实验

引言 本文主要内容是tomcat的多实例配置实验。 一、实验准备 Tomcat多实例是指在一台设备上运行多个Tomcat服务&#xff0c;这些Tomcat相互独立&#xff0c;互不影响。多实例与虚拟主机不同&#xff0c;虚拟主机的本质是在一个服务下有多个相对独立的目录&#xff0c;但是多实…

OFA(One-For-All)阿里达摩院实现架构、模态、任务的三个统一之Image Captioning

OFA(One-For-All) 通用多模态预训练模型&#xff0c;使用简单的序列到序列的学习框架统一模态&#xff08;跨模态、视觉、语言等模态&#xff09;和任务&#xff08;如图片生成、视觉定位、图片描述、图片分类、文本生成等&#xff09; 架构统一&#xff1a;使用统一的transfo…

何谓SRIO——RapidIO之旅从这里开始

何谓SRIO——RapidIO之旅从这里开始 SRIO&#xff08;Serial RapidIO&#xff09;协议是一种用于高速串行通信的协议&#xff0c;旨在连接数字信号处理器&#xff08;DSP&#xff09;、网络处理器、FPGA等芯片&#xff0c;以及它们之间的互连。SRIO协议具有低延迟、高带宽&…