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

这篇具有很好参考价值的文章主要介绍了c++11 标准模板(STL)(std::priority_queue)(四)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

适配一个容器以提供优先级队列
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;
}

输出

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

 文章来源地址https://www.toymoban.com/news/detail-428334.html

到了这里,关于c++11 标准模板(STL)(std::priority_queue)(四)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++ STL priority_queue

    目录 一.认识priority_queue 二. priority_queue的使用 三.仿函数  1.什么是仿函数  2.控制大小堆  3.TopK问题 四.模拟实现priority_queue  1.priority_queue的主要接口框架  2.堆的向上调整算法  3.堆的向下调整算法  4.仿函数控制大小堆  五.priority_queue模拟实现整体代码和测试 priority_queue-

    2024年02月07日
    浏览(43)
  • STL之priority_queue与仿函数

    1.介绍 函数对象,又称仿函数,是可以像函数一样使用的对象,其原理就是重载了函数调用符: () 因此在此类中,一定有 operator() 的成员函数。 2.示例 如果T是内置类型,则直接进行比较。如果T是自定义类型,则会调用其operator()。 先创建一个_less类型的对象smaller,对于sma

    2024年02月10日
    浏览(41)
  • 【STL】priority_queue的使用及模拟实现

    目录 前言 priority_queue的使用 功能解析 基本接口 写点题目 模拟实现 结构解析 插入删除 调整函数结合仿函数 仿函数介绍 结合使用 其他功能 接口补齐 迭代器区间构造 🍾打开 queue 头文件后,我们发现除了我们之前介绍过的普通队列以外,还有一个 priority_queue 。 🍾其又名为

    2024年02月08日
    浏览(40)
  • 【STL详解 —— priority_queue的使用与模拟实现】

    std::priority_queue 是 C++ 标准库中的容器适配器,它提供了一种基于堆的优先级队列实现。优先级队列是一种特殊的队列,其中的元素按照一定的优先级顺序排列,而不是按照它们被插入的顺序。 在 std::priority_queue 中,插入元素时会根据元素的值自动进行排序,最大(或最小)

    2024年04月17日
    浏览(31)
  • 【C++】STL之priority_queue类源码剖析

    目录 概述 算法 源码 PriorityQueue.h test.cpp 测试结果 priority_queue:优先级队列,包含在头文件queue中 优先级队列类似于堆结构,优先级最高的元素被置为堆顶,最优先被弹出top()和删除pop() 优先级队列的默认调整策略是大根堆,也就是最大值在堆顶 自定义类型需要用户自己提供

    2024年02月02日
    浏览(41)
  • 『C++ - STL』之优先级队列( priority_queue )

    什么是优先级队列,从该名中可以知道他一定有队列的一定属性,即先入先出(LILO),而这里的优先级则可以判断出它的另一个特点就是可以按照一定的条件将符合该条件的先进行出队,这就是优先级队列; 而在数据结构中有一个支持该操作的结构 - 堆( heap ); 而在STL中,这个

    2024年02月07日
    浏览(45)
  • 【C++】容器适配器之priority_queue & 仿函数

    我们和学习之前的容器一样,可以使用cplusplus官网进行学习:priority_queue文档介绍 priority_queue(优先级队列)是一种容器适配器,它 和queue使用同一个头文件,其底层结构是一个堆,并且默认情况下是一个大根堆,此外,priority_queue也不支持迭代器,这是为了不破坏堆的结构使用

    2024年02月01日
    浏览(45)
  • c++ 11标准模板(STL) std::vector (二)

    template     class T,     class Allocator = std::allocatorT class vector; (1) namespace pmr {     template class T     using vector = std::vectorT, std::pmr::polymorphic_allocatorT; } (2) (C++17 起) 1) std::vector 是封装动态数组的顺序容器。 2) std::pmr::vector 是使用多态分配器的模板别名。 元素相继存储,这意味着不

    2024年02月02日
    浏览(56)
  • c++11 标准模板(STL)(std::bitset)(四)

    template std::size_t N class bitset;  类模板 bitset 表示一个 N 位的固定大小序列。可以用标准逻辑运算符操作位集,并将它与字符串和整数相互转换。 bitset 满足 可复制构造 (CopyConstructible) 及 可复制赋值 (CopyAssignable) 的要求。 模板形参 N - 要为 bitset 分配存储的位数 成员类型 refer

    2024年02月08日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包