C++STL----优先队列

一、优先队列原理

  队列(queue)是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。

  优先队列(priority_queue)容器与队列一样,只能从队尾插入元素,从队首删除元素。但是它有一个特性,队列中最大的元素总是位于队首。出队时,并非按照先进先出的原则进行,而是将当前队列中最大的元素出队。这点类似于给队列里的元素进行了由大到小的顺序排序。元素的比较规则默认按元素值由大到小排序,可以重载“<”操作符来重新定义比较规则。

  优先队列基于二叉堆实现。

 二叉堆(Heap)

  堆是一种特殊的二叉树,性质如下:

  1. 每个结点的值都大于或等于其左右孩子结点的值(大顶堆),或每个结点的值都小宇或等于其左右孩子的值(小顶堆)。
  2. 必须满足完全二叉树的结构。

  优先队列的时间复杂度为O(logn),n为队列中元素的个数,其存取都需要时间。

二、使用方式

  优先队列模板声明带有三个参数,priority_queue<Type, Container, Functional>, 其中Type为数据类型,Container为保存数据的容器,Functional为元素比较方式。

优先级队列可以用向量(vector)或双向队列(deque)来实现。(注意list不能用来实现队列,因为list的迭代器不是任意存取iterator,而pop中用到堆排序时是要求randomaccess iterator 的!) Container必须是用数组实现的容器,比如 vector, deque. STL里面默认用的是vector。比较方式默认用operator< , 所以如果把后面两个参数缺省的话,优先队列就是大顶堆,队头元素最大。

头文件:#include <queue>

基本操作: 

  empty()      如果队列为空,则返回真

  pop()    删除对顶元素,删除第一个元素

  push()        加入一个元素

  size()      返回优先队列中拥有的元素个数

  top()     返回优先队列对顶元素,返回优先队列中有最高优先级的元素

  在默认的优先队列中,优先级高的先出队。在默认的int型中先出队的为较大的数。

声明方式

1、普通方法:

  priority_queue<int> q;                   //通过操作,按照元素从大到小的顺序出队
  priority_queue<int,vector<int>, greater<> > q;      //通过操作,按照元素从小到大的顺序出队

2、自定义优先级:

  struct cmp {     
    bool operator()(int x, int y)     
    {        
       return x > y;   // x小的优先级高       //也可以写成其他方式,如: return p[x] > p[y];表示p[i]小的优先级高
    }
  };
  priority_queue<int, vector<int>, cmp> q;      //定义方法
                      //其中,第二个参数为容器类型。第三个参数为比较函数。

3、结构体声明方式:

  struct node {     
    int x, y;     
       bool operator < (node a, node b)     
    {         
      return a.x > b.x;    //结构体中,x小的优先级高     
    }
  };
  priority_queue<node>q;  //定义方法
             //在该结构中,y为值, x为优先级。
             //通过自定义 operator< 操作符来比较元素中的优先级。
             //在重载”<”时,最好不要重载”>”,可能会发生编译错误
 

三、代码实现

复制代码
 1 #include <iostream>
 2 #include <queue>
 3 
 4 using namespace std;、
 5 struct number1 {
 6     int x;
 7     bool operator<(const number1 &a) const {
 8         return x > a.x;    // 最小值优先
 9     }
10     friend ostream &operator<<(ostream &out, const number1 &s) {
11         out << s.x;
12         return out;
13     }
14 };
15 struct number2 {
16     int x;
17     bool operator<(const number2 &a) const {
18         return x < a.x;    // 最大值优先
19     }
20     friend ostream &operator<<(ostream &out, const number2 &s) {
21         out << s.x;
22         return out;
23     }
24 };
25 int main() {
26     int a[] = { 14, 10, 56, 7, 83, 22, 36, 91, 3, 47, 72, 0 };
27     number1 num1[] = { 14, 10, 56, 7, 83, 22, 36, 91, 3, 47, 72, 0 };
28     number2 num2[] = { 14, 10, 56, 7, 83, 22, 36, 91, 3, 47, 72, 0 };
29 
30     priority_queue<int> que;    // 采用默认优先级构造队列
31 
32     priority_queue<int, vector<int>, less<>> que1;       // 最大值优先
33     priority_queue<int, vector<int>, greater<>> que2;    // 最小值优先
34     /* 自定义数据类型 */
35     priority_queue<number1> que3;
36     priority_queue<number2> que4;
37     int i;
38     for (i = 0; a[i]; i++) {
39         que.push(a[i]);
40         que1.push(a[i]);
41         que2.push(a[i]);
42     }
43     for (i = 0; num1[i].x; i++)
44         que3.push(num1[i]);
45     for (i = 0; num2[i].x; i++)
46         que4.push(num2[i]);
47     cout << "采用默认优先关系:\npriority_queue<int> que\n";
48     while (!que.empty()) {
49         cout << que.top() << " ";
50         que.pop();
51     }
52     cout << "\n----------------------------------------------" << endl;
53     cout << "采用最大值优先关系:\npriority_queue<int> que1\n";
54     while (!que1.empty()) {
55         cout << que1.top() << " ";
56         que1.pop();
57     }
58     cout << "\n----------------------------------------------" << endl;
59     cout << "采用最小值优先关系:\npriority_queue<int> que2\n";
60     while (!que2.empty()) {
61         cout << que2.top() << " ";
62         que2.pop();
63     }
64     cout << "\n----------------------------------------------" << endl;
65     cout << "采用自定义数据类型最小值优先关系:\npriority_queue<number1> que3\n";
66     while (!que3.empty()) {
67         cout << que3.top() << " ";
68         que3.pop();
69     }
70     cout << "\n----------------------------------------------" << endl;
71     cout << "采用自定义数据类型最大值优先关系:\npriority_queue<number2> que4\n";
72     while (!que4.empty()) {
73         cout << que4.top() << " ";
74         que4.pop();
75     }
76     return 0;
77 }
复制代码

注意:队列遍历输出所有对顶元素后,队列就为空

posted @   Happinesspill  阅读(420)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示