C ++: The difference between queue and priority_queue

Introduction of queue

Document introduction of queue

translation:

  1. A queue is a container adapter designed to operate in a FIFO context (first-in-first-out), where elements are inserted from one end of the container and extracted from the other end.

  2. The queue is implemented as a container adapter, which encapsulates a specific container class as its underlying container class, and queue provides a specific set of member functions to access its elements. Elements enter the queue from the end of the team and exit the queue from the head of the team.

  3. The underlying container can be one of the standard container class templates or other specially designed container classes. The underlying container should support at least the following operations:
    empty: detect whether the queue is empty
    size: return the number of valid elements in the queue
    front: return the reference of the head element
    back: return the reference of the tail element
    push_back: enter the queue at the end of the queue
    pop_front : Leave the queue at the head of the queue

  4. The standard container classes deque and list meet these requirements. By default, if no container class is specified for queue instantiation, the standard container deque is used.

Use of queue

Function declaration Interface Description
queue() Construct an empty queue
empty() Check if the queue is empty, return true, otherwise return false
size() Returns the number of valid elements in the queue
front() Return a reference to the head element
back() Return a reference to the tail element
push() Val elements into the queue at the end of the queue
pop() Remove the head element from the queue

Introduction of priority_queue

priority_queue document introduction

translation:

  1. The priority queue is a container adapter. According to strict weak ordering criteria, its first element is always the largest of the elements it contains.

  2. This context is similar to the heap, where elements can be inserted at any time, and only the largest heap element (the top element in the priority queue) can be retrieved.

  3. The priority queue is implemented as a container adapter, which encapsulates a specific container class as its underlying container class, and queue provides a specific set of member functions to access its elements. Elements pop out from the "tail" of a particular container, which is called the top of the priority queue.

  4. The underlying container can be any standard container class template, or it can be a container class of other specific designs. The container should be accessible through a random access iterator, and supports the following operations:
    empty (): detects whether the container is empty
    size (): returns the number of valid elements in the container
    front (): returns the reference of the first element in the container
    push_back ( ): Insert element
    pop_back () at the end of the container: delete the element at the end of the container

  5. The standard container classes vector and deque meet these needs. By default, if no container class is specified for a particular priority_queue class instantiation, vector is used.

  6. Random access iterators need to be supported so that the heap structure is always maintained internally. The container adapter automatically completes this operation by automatically calling the algorithm functions make_heap, push_heap, and pop_heap when needed.

Use of priority_queue

The priority queue uses vector as its underlying storage container by default, and a heap algorithm is used on the vector to construct the elements in the vector into a heap structure. Therefore, priority_queue is the heap. Priority_queue can be considered for all locations where the heap is needed .

Function declaration Interface Description
priority_queue()/priority_queue(first, last) Construct an empty priority queue
empty( ) Check if the priority queue is empty, return true, otherwise return false
top( ) Returns the largest (smallest element) in the priority queue, which is the top element of the heap
push(x) Insert element x in priority queue
pop() Delete the largest (smallest) element in the priority queue, which is the top element of the heap

note:

  1. By default priority_queue is a large heap.

Demo code:

#include <iostream>
#include <vector>
#include <queue>
#include <functional> // greater算法的头文件
using namespace std;

void TestPriorityQueue()
{
    // 默认情况下,创建的是大堆,其底层按照小于号比较 
    vector<int> v{3,2,7,6,0,4,1,9,8,5}; 
    priority_queue<int> q1;
    for (auto& e : v)
        q1.push(e);
    cout << q1.top() << endl;   // 9
    // 如果要创建小堆,将第三个模板参数换成greater比较方式
    priority_queue<int, vector<int>, greater<int>> q2(v.begin(), v.end()); 
    cout << q2.top() << endl;   // 0
}
  1. If you put custom type data in priority_queue, users need to provide overload of> or <in custom type.
class Date
{
    int _year;
    int _month;
    int _day;
public:
    Date(int year = 1900, int month = 1, int day = 1)
        : _year(year)
        , _month(month)
        , _day(day)
    {}

    bool operator<(const Date& d)const
    {
        return (_year < d._year) ||
            (_year == d._year && _month < d._month) ||
            (_year == d._year && _month == d._month && _day < d._day);
    }

    bool operator>(const Date& d)const
    {
        return (_year > d._year) ||
            (_year == d._year && _month > d._month) ||
            (_year == d._year && _month == d._month && _day > d._day);
    }

    friend ostream& operator<<(ostream& _cout, const Date& d)
    {
        _cout << d._year << "-" << d._month << "-" << d._day;
        return _cout;
    } 
};

void TestPriorityQueue()
{
    // 大堆,需要用户在自定义类型中提供<的重载 
    priority_queue<Date> q1; 
    q1.push(Date(2018, 10, 29)); 
    q1.push(Date(2018, 10, 28)); 
    q1.push(Date(2018, 10, 30));
    cout << q1.top() << endl;   // 2018, 10, 30
    
    // 如果要创建小堆,需要用户提供>的重载 
    priority_queue<Date, vector<Date>, greater<Date>> q2; 
    q2.push(Date(2018, 10, 29));
    q2.push(Date(2018, 10, 28));
    q2.push(Date(2018, 10, 30));
    cout << q2.top() << endl;   // 2018, 10, 28
}
  1. In some cases, users may need to provide comparator rules
class Less
{
public:
    bool operator()(const Date* pLeft, const Date* pRight)
    {
        return *pLeft < *pRight;
    }
};

void TestPriorityQueue()
{
    // 自己定制比较的规则
    priority_queue<Date*, vector<Date*>, Less> q; 
    q.push(&Date(2018, 10, 29)); 
    q.push(&Date(2018, 10, 28)); 
    q.push(&Date(2018, 10, 30));
    cout << *q.top() << endl;   // 2018, 10, 30
}
发布了152 篇原创文章 · 获赞 45 · 访问量 1万+

Guess you like

Origin blog.csdn.net/AngelDg/article/details/105323079