优先队列c++ STL用法

    xiaoxiao2021-12-14  15

    优先队列(priority queue) 普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出 (first in, largest out)的行为特征。

    优先队列是队列的一种,不过它可以按照自定义的一种方式(数据的优先级)来对队列中的数据进行动态的排序

    每次的push和pop操作,队列都会动态的调整,以达到我们预期的方式来存储。

    例如:我们常用的操作就是对数据排序,优先队列默认的是数据大的优先级高

    所以我们无论按照什么顺序push一堆数,最终在队列里总是top出最大的元素。

     优先队列的常用操作

    优先级队列支持的操作

    q.empty()         如果队列为空,则返回true,否则返回false

    q.size()            返回队列中元素的个数

    q.pop()             删除队首元素,但不返回其值

    q.top()             返回具有最高优先级的元素值,但不删除该元素

    q.push(item)     在基于优先级的适当位置插入新元素

    用法:

    示例:将元素5,3,2,4,6依次push到优先队列中,print其输出。

    1. 标准库默认使用元素类型的<操作符来确定它们之间的优先级关系。

    priority_queue<int> pq;

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

     

    2. 数据越小,优先级越高

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

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

    3. 自定义优先级,重载比较符号

    重载默认的 < 符号

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

    这时,需要为每个元素自定义一个优先级。

    注:重载>号会编译出错,因为标准库默认使用元素类型的<操作符来确定它们之间的优先级关系。 而且自定义类型的<操作符与>操作符并无直接联系

    #include<iostream> #include<functional> #include<queue> using Namespace stdnamespace 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; } 先级队列可以用向量(vector)或双向队列(deque)来实现(注意list container 不能用来实现queue,因为list 的迭代器不是任意存取iterator,而pop 中用到堆排序时是要求randomaccess iterator 的!): priority_queue<vector<int>, less<int>> pq1; // 使用递增less<int>函数对象排序 priority_queue<deque<int>, greater<int>> pq2; // 使用递减greater<int>函数对象排序 其成员函数有“判空(empty)” 、“尺寸(Size)” 、“栈顶元素(top)” 、“压栈(push)” 、“弹栈(pop)”等。 例:  1  #include  < iostream >  2  #include  < queue >    3  using   namespace  std;  4     5  class  T {  6  public :  7       int  x, y, z;   8      T( int  a,  int  b,  int  c):x(a), y(b), z(c)  9      {  10      } 11  }; 12  bool   operator   <  ( const  T  & t1,  const  T  & t2)  13  { 14       return  t1.z  <  t2.z;  //  按照z的顺序来决定t1和t2的顺序 15  16  main() 17  18      priority_queue < T >  q;  19      q.push(T( 4 , 4 , 3 ));  20      q.push(T( 2 , 2 , 5 ));  21      q.push(T( 1 , 5 , 4 ));  22      q.push(T( 3 , 3 , 6 ));  23       while  ( ! q.empty())  24      {  25          T t  =  q.top();  26          q.pop();  27          cout  <<  t.x  <<   "   "   <<  t.y  <<   "   "   <<  t.z  <<  endl;  28      }  29       return   1 30  }       输出结果为(注意是按照z的顺序从大到小出队的):        3 3 6        2 2 5        1 5 4        4 4 3       再看一个按照z的顺序从小到大出队的例子:  1  #include  < iostream >    2  #include  < queue >    3  using   namespace  std;   4  class  T   5   6  public  7       int  x, y, z;   8      T( int  a,  int  b,  int  c):x(a), y(b), z(c)   9      { 10      }  11  };  12  bool   operator   >  ( const  T  & t1,  const  T  & t2)  13  14       return  t1.z  >  t2.z;  15  16  main()  17  18      priority_queue < T, vector < T > , greater < T >   >  q;  19      q.push(T( 4 , 4 , 3 ));  20      q.push(T( 2 , 2 , 5 ));  21      q.push(T( 1 , 5 , 4 ));  22      q.push(T( 3 , 3 , 6 ));  23       while  ( ! q.empty())  24      {  25          T t  =  q.top();  26          q.pop();  27          cout  <<  t.x  <<   "   "   <<  t.y  <<   "   "   <<  t.z  <<   endl;  28      }  29       return   1 30  }       输出结果为:        4 4 3        1 5 4        2 2 5        3 3 6       如果我们把第一个例子中的比较运算符重载为: bool operator < (const T &t1, const T &t2) { return t1.z > t2.z; // 按照z的顺序来决定t1和t2的顺序} 则第一个例子的程序会得到和第二个例子的程序相同的输出结果。
    转载请注明原文地址: https://ju.6miu.com/read-972184.html

    最新回复(0)