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>::operator=

priority_queue& operator=( const priority_queue& other );

(1)

priority_queue& operator=( priority_queue&& other );

(2) (C++11 起)

other 的内容替换容器适配器的内容。

1) 复制赋值运算符。以 other 的内容副本替换内容。等效地调用 c = other.c; comp = other.comp; 。(隐式声明)

2) 移动赋值运算符。用移动语义以 other 的内容替换内容。等效地调用 c = std::move(other.c); comp = std::move(other.comp); 。(隐式声明)

参数

other - 用作源的另一容器适配器

返回值

*this

复杂度

等价于底层容器 operator= 的复杂度。

容量

检查底层的容器是否为空

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

bool empty() const;

(C++20 前)

[[nodiscard]] bool empty() const;

(C++20 起)

检查底层容器是否为空,即是否 c.empty() 。

参数

(无)

返回值

若底层容器为空则为 true ,否则为 false 。

复杂度

常数

返回容纳的元素数

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

size_type size() const;

返回底层容器中的元素数,即 c.size() 。

参数

(无)

返回值

容器中的元素数。

复杂度

常数。

调用示例

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

    //以 other 的内容替换容器适配器的内容。
    //1) 复制赋值运算符。以 other 的内容副本替换内容。
    //等效地调用 c = other.c; comp = other.comp;
    std::priority_queue<Cell> queue2 = queue1;
    queuePrint("queue2:   ", queue2);
    std::cout << std::endl;

    //以 other 的内容替换容器适配器的内容。
    //2) 移动赋值运算符。用移动语义以 other 的内容替换内容。
    //等效地调用 c = std::move(other.c); comp = std::move(other.comp);
    std::priority_queue<Cell> queue3 = std::move(queue1);
    queuePrint("queue3:   ", queue3);
    //检查底层容器是否为空,即是否 c.empty() 。
    std::cout << "queue1 empty: " << queue1.empty() << std::endl;
    std::cout << std::endl;

    //检查底层容器是否为空,即是否 c.empty() 。
    while (!queue3.empty())
    {
        //返回底层容器中的元素数,即 c.size() 。
        std::cout << "queue3.size(): " << queue3.size() << "    ";
        std::cout << "queue3.top(): " << queue3.top() << std::endl;
        queue3.pop();
    }

    return 0;
}

输出

猜你喜欢

转载自blog.csdn.net/qq_40788199/article/details/130332941
今日推荐