• 【转】 STL里的priority_queue用法,有这个东西太好了


    在STL里有这个priority_queue,实现优先队列的结构。在优先队列中,优先级高的元素先出队列。
    现在在这里说说用法吧

    先看看语法:

    Syntax:

    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 and a 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 or pop, respectively) to grant that the element popped is always the greater in the priority queue.

    可以自定义一个比较类,Compare

    其实就三种用法

    第一种,直接使用默认的。

    它的模板声明带有三个参数,priority_queue<Type, Container, Functional>
    Type 为数据类型, Container 为保存数据的容器,Functional 为元素比较方式。
    Container 必须是用数组实现的容器,比如 vector, deque 但不能用 list.
    STL里面默认用的是 vector. 比较方式默认用 operator< , 所以如果你把后面俩个
    参数缺省的话,优先队列就是大顶堆,队头元素最大。
    看例子


    priority_queue<int> qi;

        int a[len] = {3,5,9,6,2};

        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();
        }

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

    第二种:

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

    如果要用到小顶堆,则一般要把模板的三个参数都带进去。
    STL里面定义了一个仿函数 greater<>,对于基本类型可以用这个仿函数声明小顶堆
    priority_queue<int, vector<int>, greater<int> >qi2;

    对于自定义类型,则必须自己重载 operator< 或者自己写仿函数

    #include <iostream>
    #include <queue>

    using namespace std;

    struct Node{
        int x, y;
        Node( int a= 0, int b= 0 ):
            x(a), y(b) {}
    };

    bool operator<( Node a, Node b ){
        if( a.x== b.x ) return a.y> b.y;
        return a.x> b.x; 
    }

    int main(){
        priority_queue<Node> q;
        
        for( int i= 0; i< 10; ++i )
        q.push( Node( rand(), rand() ) );
        
        while( !q.empty() ){
            cout << q.top().x << ' ' << q.top().y << endl;
            q.pop();
        }
        
        getchar();
        return 0;
    }

    或者这样定义也是能达到效果的:

    struct Node{
        int x, y;
        Node( int a= 0, int b= 0 ):
            x(a), y(b) {}

        friend operator<( Node a, Node b ){
        if( a.x== b.x ) return a.y> b.y;
        return a.x> b.x;

        }
    };

    自定义类型重载 operator< 后,声明对象时就可以只带一个模板参数。
    但此时不能像基本类型这样声明
    priority_queue<Node, vector<Node>, greater<Node> >;
    原因是 greater<Node> 没有定义,如果想用这种方法定义
    则可以按如下方式

    例子:

    #include <iostream>
    #include <queue>

    using namespace std;

    struct Node{
        int x, y;
        Node( int a= 0, int b= 0 ):
            x(a), y(b) {}
    };

    struct cmp{
        bool operator() ( Node a, Node b ){
            if( a.x== b.x ) return a.y> b.y;
            
            return a.x> b.x; }
    };

    int main(){
        priority_queue<Node, vector<Node>, cmp> q;
        
        for( int i= 0; i< 10; ++i )
        q.push( Node( rand(), rand() ) );
        
        while( !q.empty() ){
            cout << q.top().x << ' ' << q.top().y << endl;
            q.pop();
        }
        
        getchar();
        return 0;
    }

    还有一点要注意的是priority_queue中的三个参数,后两个可以省去,因为有默认参数,不过如果,有第三个参数的话,必定要写第二个参数。

  • 相关阅读:
    vlc代码分析(3)——输入模块
    vlc学习计划(4)在EMACS中使用GDB调试
    There Are Free RTSP DirectShow Source Filters with full source code
    HDU 4283 You Are the One 第37届ACM/ICPC 天津赛区网络赛 1006题 (DP)
    HDU 4276 The Ghost Blows Light 第37届ACM/ICPC长春赛区1010题 (树形DP)
    POJ 1459 Power Network 最大流 dinic模板
    HDU 4273 Rescue 第37届ACM/ICPC 长春赛区网络赛1007题(三维凸包+重心+点面距离)
    HDU 4286 Data Handler 第37届ACM/ICPC 天津赛区网络赛1009题 (双向链表模拟)
    POJ 2246 ZOJ 1094 Matrix Chain Multiplication(简单题)
    HDU 4280 Island Transport 第37届ACM/ICPC 天津网络赛1003题 (最大流模板题,高效SAP模板)
  • 原文地址:https://www.cnblogs.com/iammatthew/p/1803935.html
Copyright © 2020-2023  润新知