zoukankan      html  css  js  c++  java
  • STL中的priority_queue

    class template

    priority_queue

    <queue>
    Priority queue

    Priority queues are a type of container adaptors, specifically designed such that its first element is always the greatest of the elements it contains, according to some strict weak ordering condition.

    This context is similar to a heap where only the max heap element can be retrieved (the one at the top in the priority queue) and elements can be inserted indefinitely.

    Priority queues are implemented as container adaptors, which are classes that use an encapsulated object of a specific container class as its underlying container, providing a specific set of member functions to access its elements. Elements are popped from the "back" of the specific container, which is known as the top of the priority queue.

    The underlying container may be any of the standard container class templates or some other specifically designed container class. The only requirement is that it must be accessible through random access iterators and it must support the following operations:

    • front()
    • push_back()
    • pop_back()


    Therefore, the standard container class templates vector and deque can be used. By default, if no container class is specified for a particular priority_queue class, the standard container class template vector is used.

    Support for random access iterators is required to keep a heap structure internally at all times. This is done automatically by the container adaptor by calling the algorithms make_heappush_heap and pop_heap when appropriate.

    In their implementation in the C++ Standard Template Library, priority queues take three template parameters:

    1
    2
    template < class T, class Container = vector<T>,
               class Compare = less<typename Container::value_type> > class priority_queue;


    Where the template parameters have the following meanings:

    • T: Type of the elements.
    • Container: Type of the underlying container object used to store and access the elements.
    • Compare: Comparison class: A class such that the expression comp(a,b), where comp is an object of this class anda and b are elements of the container, returns true if a is to be placed earlier than b in a strict weak ordering operation. This can either be a class implementing a function call operator or a pointer to a function. This defaults to less<T>, which returns the same as applying the less-than operator (a<b).
      The priority_queue object uses this expression when an element is inserted or removed from it (using push orpop, respectively) to grant that the element popped is always the greatest in the priority queue.

    In the reference for the priority_queue member functions, these same names (TContainer and Compare) are assumed for the template parameters.

    Member functions

    priority_queue是一种容器适配器。容器适配器的意思就是说其底层实现依赖于某一特定容器,使用该容器来存储数据。容器适配器只是对该容器的一层封装,以满足上下文应用的需要。容器适配器对其成员函数的调用最终是对容器的函数的调用。C++ STL中定义了三种Container Adapter:Stack(LIFO)、Queue(FIFO)和Priority_queue(max heap)。其中priority_queue底层封装的容器默认是vector。

    priority_queue构造的好像是大根堆,而且当插入或删除元素时会自动调用“algorithm.h”(主要是STL中常用算法)文件中的 make_heappush_heap and pop_heap函数来调整,使其保持大根堆的特性。由于是大根堆,每次调用top()函数将会返回priority_queue中最大值的引用。

    注意:priority_queue的定义在头文件“queue.h”中,所以使用时要添加

    #include <queue>

    下面这个例子就很好地说明了priority_queue的内部存储结构:

    // priority_queue::push/pop
    #include <iostream>
    #include <queue>
    using namespace std;
    
    int main ()
    {
      priority_queue<int> mypq;
    
      mypq.push(30);
      mypq.push(100);
      mypq.push(25);
      mypq.push(40);
    
      cout << "Popping out elements...";
      while (!mypq.empty())
      {
         cout << " " << mypq.top();
         mypq.pop();
      }
      cout << endl;
    
      return 0;
    }

    以下转自:http://www.cnblogs.com/vvilp/articles/1504436.html

    在优先队列中,优先级高的元素先出队列。
    标准库默认使用元素类型的<操作符来确定它们之间的优先级关系。
    优先队列的第一种用法,也是最常用的用法:

    priority_queue<int> qi;

    通过<操作符可知在整数中元素大的优先级高。
    故示例1中输出结果为:9 6 5 3 2

    第二种方法:
    在示例1中,如果我们要把元素从小到大输出怎么办呢?
    这时我们可以传入一个比较函数,使用functional.h函数对象作为比较函数。

    priority_queue<int, vector<int>, greater<int> >qi2;

    其中
    第二个参数为容器类型。
    第二个参数为比较函数。
    故示例2中输出结果为:2 3 5 6 9

    第三种方法:
    自定义优先级。

    struct node
    {
        
    friend bool operator< (node n1, node n2)
         {
            
    return n1.priority < n2.priority;
         }
        
    int priority;
        
    int value;
    };

    在该结构中,value为值,priority为优先级。
    通过自定义operator<操作符来比较元素中的优先级。
    在示例3中输出结果为:
    优先级 值
    9           5
    8          2
    6           1
    2           3
    1           4
    但如果结构定义如下:

    struct node
    {
        
    friend bool operator> (node n1, node n2)
         {
            
    return n1.priority > n2.priority;
         }
        
    int priority;
        
    int value;
    };

    则会编译不过(G++编译器)
    因为标准库默认使用元素类型的<操作符来确定它们之间的优先级关系。
    而且自定义类型的<操作符与>操作符并无直接联系,故会编译不过。

    //代码清单

    #include<iostream>
    #include
    <functional>
    #include
    <queue>
    using 
    namespace std;
    struct node
    {
        
    friend bool operator< (node n1, node n2)
         {
            
    return n1.priority < n2.priority;
         }
        
    int priority;
        
    int value;
    };
    int main()
    {
        
    const int len = 5;
        
    int i;
        
    int a[len= {3,5,9,6,2};
        
    //示例1
         priority_queue
    <int> qi;
        
    for(i = 0; i < len; i++)
             qi.push(a[i]);
        
    for(i = 0; i < len; i++)
         {
             cout
    <<qi.top()<<" ";
             qi.pop();
         }
         cout
    <<endl;
        
    //示例2
         priority_queue
    <int, vector<int>, greater<int> >qi2;
        
    for(i = 0; i < len; i++)
             qi2.push(a[i]);
        
    for(i = 0; i < len; i++)
         {
             cout
    <<qi2.top()<<" ";
             qi2.pop();
         }
         cout
    <<endl;
        
    //示例3
         priority_queue
    <node> qn;
         node b[
    len];
         b[
    0].priority = 6; b[0].value = 1
         b[
    1].priority = 9; b[1].value = 5
         b[
    2].priority = 2; b[2].value = 3
         b[
    3].priority = 8; b[3].value = 2
         b[
    4].priority = 1; b[4].value = 4

        
    for(i = 0; i < len; i++)
             qn.push(b[i]);
         cout
    <<"优先级"<<'\t'<<"值"<<endl;
        for(i = 0; i < len; i++)
         {
             cout
    <<qn.top().priority<<'\t'<<qn.top().value<<endl;
             qn.pop();
         }
        
    return 0;
    }
  • 相关阅读:
    【编程思想】【设计模式】【结构模式Structural】适配器模式adapter
    【编程思想】【设计模式】【结构模式Structural】3-tier
    【编程思想】【设计模式】【创建模式creational】原形模式Prototype
    【编程思想】【设计模式】【创建模式creational】Pool
    【编程思想】【设计模式】【创建模式creational】lazy_evaluation
    【编程思想】【设计模式】【创建模式creational】Borg/Monostate
    【编程思想】【设计模式】【创建模式creational】抽象工厂模式abstract_factory
    【编程思想】【设计模式】【创建模式creational】建造者模式builder
    【编程思想】【设计模式】【行为模式Behavioral】策略模式strategy
    【编程思想】【设计模式】【创建模式creational 】工厂模式factory_method
  • 原文地址:https://www.cnblogs.com/wanghetao/p/2513514.html
Copyright © 2011-2022 走看看