zoukankan      html  css  js  c++  java
  • 优先级队列用法详解(priority_queue)

    由于优先级队列的内部数据结构为 ,所以这里先介绍堆的一些操作。

    堆的一些函数操作在algorithm头文件中

    //在[first, last)范围内构造最大堆,first,last 可以是vector指针也可以是数组指针
    make_heap(first ,last)
    make_heap(first ,last, cmpObject)

      默认情况下是建立最大堆,即首元素为两个地址间的最大值。默认为less<int>,可以改为greater<int>即为建立最小堆

    pop_heap(first ,last)
    pop_heap(first ,last, cmpObject)

    将front(即第一个最大元素)移动到end的前部,同时将剩下的元素重新构造成(堆排序)一个新的heap。

    push_heap(first ,last)
    push_heap(first ,last, cmpObject)

    对刚插入的(尾部)元素做堆排序。在进行push_heap操作之前,除了最后一个元素以外的其他元素必须构成一个最大堆,

    否则会报错。

    sort_heap(first ,last)
    sort_heap(first ,last, cmpObject)

    将一个堆做排序,最终成为一个有序的系列,可以看到sort_heap时,必须先是一个堆(两个特性:1、最大元素在第一个 2、添加或者删除元素以对数时间),因此必须先做一次make_heap.

    先写一个用 STL 里面堆算法实现的与真正的STL里面的priority_queue 用法相
    似的 priority_queue,以加深对priority_queue 的理解

    #include <iostream>
    #include <algorithm>
    #include <vector>
    
     using namespace std;
    
     class priority_queue
    {
        private:
            vector<int> data;
        public:
            void push( int t ){
                data.push_back(t);
                push_heap( data.begin(), data.end());
            }
            void pop(){
                pop_heap( data.begin(), data.end() );
                data.pop_back();
            }
            int top()    { return data.front(); }
            int size()   { return data.size();  }
            bool empty() { return data.empty(); }
    };
    
     int main()
    {
        priority_queue  test;
        test.push( 3 );
        test.push( 5 );
        test.push( 2 );
        test.push( 4 );
        test.push(10);
        test.push(1);
        while( !test.empty() ){
            cout << test.top() << endl;
                test.pop(); }
        return 0;
    }

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

    下面的程序为建立一个最小堆的例子 priority_queue<int,vector<int>,greater<int>> q;

    #include <iostream>
    #include <queue>
    
     using namespace std;
    
     int main(){
        priority_queue<int, vector<int>, greater<int> > q;
        for( int i= 0; i< 10; ++i ) q.push( rand() );
        while( !q.empty() ){
            cout << q.top() << endl;
            q.pop();
        }
        getchar();
        return 0;
    }
    View Code

    自定义类型Node的优先级队列,重载比较运算符'<':

    #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;
    }
    View Code

    重载‘<’之后可以只带一个模板参数定义优先级队列对象,但不能声明priority_queue<Node, vector<Node>, greater<Node> >

    这种类型,原因是greater<Node>没有定义,要想定义上述形式必须定义一个比较的类cmp,具体实现如下代码。

    #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;
    }
    View Code

    参考博文:

      http://blog.163.com/zjut_nizhenyang/blog/static/1695700292010101632059540/

      http://blog.csdn.net/fuyufjh/article/details/47144869

      http://blog.sina.com.cn/s/blog_959bf1d3010191h1.html

  • 相关阅读:
    从FxCop归纳出来的一些规范建议
    UML用例建模的慨念和应用
    Android 截屏脚本
    悲剧的账户绑定与通讯录丢失实录
    文件分享功能实现
    Java字符串与整数之间的互相转换
    关于大的Bitmap保存问题
    将程序关联成Android系统默认打开程序
    关于Android应用多语言支持实现
    关于通过getWidth与getHeight获取bitmap​的尺寸与其实际尺寸不符合问题
  • 原文地址:https://www.cnblogs.com/NeilZhang/p/6485013.html
Copyright © 2011-2022 走看看