优先队列知识点

来源:互联网 发布:java用于计算的类 编辑:程序博客网 时间:2024/06/08 05:21

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


优先队列(priority queue)是0个或多个元素的集合,每个元素都有一个优先权或值,对优先队列执行的操作有1) 查找;2) 插入一个新元素;3) 删除。在最小优先队列(min priorityq ueue)中,查找操作用来搜索优先权最小的元素,删除操作用来删除该元素;对于最大优先队列(max priority queue),查找操作用来搜索优先权最大的元素,删除操作用来删除该元素。优先权队列中的元素可以有相同的优先权,查找与删除操作可根据任意优先权进行。
最大优先权队列的抽象数据类型描述如ADT 9-1所示,最小优先队列的抽象数据类型描述与之类似,只需将最大改为最小即可。

抽象数据类型M axPriorityQueue
有限的元素集合,每个元素都有一个优先权操作
C reate ( ):创建一个空的优先队列

Size ( ):返回队列中的元素数目

Max ( ):返回具有最大优先权的元素
I nsert (x):将x插入队列
DeleteMax (x):从队列中删除具有最大优先权的元素,并将该元素返回至x;

其实就三种用法
第一种,直接使用默认的。
它的模板声明带有三个参数,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中的三个参数,后两个可以省去,因为有默认参数,不过如果,有第三个参数的话,必定要写第二个参数。
 


0 0
原创粉丝点击