• priority_queue


    priority_queue也叫优先级队列,说是叫队列,实际上是一个堆。

    priority_queue的接口:

     这些接口可以直接使用vector作为底层来使用:

     为什么说priority_queue是堆呢,写一段如下代码:

    1. void priority()
    2. {
    3. priority_queue<int> pq;
    4. pq.push(1);
    5. pq.push(2);
    6. pq.push(3);
    7. pq.push(4);
    8. while (!pq.empty())
    9. {
    10. cout << pq.top() << " ";
    11. pq.pop();
    12. }cout << endl;
    13. }

     main函数调用运行:

     发现结果自己按照大堆排序了,它可以排序的原因是因为它的底层是堆,用了堆的向上调整,向下调整。

     可以大堆排序就可以小堆排序。priority_queue的模版里可以传三个实例:我们需要再往模版里再传个vector实例,再传个排序实例,升序是great,降序是less:

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

    除了用vector作为实例还可以用deque,因为priority_queue的底层是堆,堆的向上向下调整是用下标进行调整的,deque也有operator[ ]。

    课习题215. 数组中的第K个最大元素 - 力扣(LeetCode)

    215. 数组中的第K个最大元素 - 力扣(LeetCode)

    首先用队列进行一下排序,也就是topk排序,排出最大的前k个:

     然后把数组传给我们的pq;

    priority_queue有个构造函数可以传区间:

     把nums传进来:

     第二步:第四步,返回顶部:

     测试未通过:

     分析:要找第二大的,只需要把第一大的去掉就-行了,所以k只减一次就够了,而不是减几次,所以应该是--k,而不是k--:

    1. class Solution {
    2. public:
    3. int findKthLargest(vector<int>& nums, int k) {
    4. priority_queue<int> pq(nums.begin(),nums.end());
    5. while(--k)
    6. {
    7. pq.pop();
    8. }
    9. return pq.top();
    10. }
    11. };

    模拟实现priority_queue

    首先写一下push:

    1. #include
    2. namespace bitt
    3. {
    4. template<class T,class Containter=vector >
    5. class priority_queue
    6. {
    7. public:
    8. void push(int child);
    9. {
    10. }
    11. private:
    12. Container _con;
    13. };
    14. }

    根据我们写堆的经验堆里面进行增删查改是怎么弄的?

    例如这样的一个堆:假设我们要在末尾插入一个20:

    _con.push_back(x);

    那它就不是一个堆了,要想让它还是保持为一个堆需要写一个向上调整函数。

    1. void adjust_queue(int child)
    2. {
    3. int parent = (child - 1 )/ 2;
    4. while (child > 0)
    5. {
    6. if (_con[parent] >_con[ child])
    7. {
    8. swap(_con[parent],_con[child]);
    9. child = parent;
    10. parent = (child - 1) / 2;
    11. }
    12. else
    13. {
    14. break;
    15. }
    16. }
    17. }

    然后是删除值,删除值是先把头尾交换一下:

    然后用向下调整法进行调整法 :

    然后在写一些size(),empty(),top():

    1. const T& top()
    2. {
    3. return _con[0];
    4. }
    5. bool empty()
    6. {
    7. return _con.empty();
    8. }
    9. size_t size()
    10. {
    11. return _con.size();
    12. }

     main函数调用运行:

    1. void test111()
    2. {
    3. bitt::priority_queue<int> pq;
    4. pq.push(1);
    5. pq.push(2);
    6. pq.push(3);
    7. pq.push(4);
    8. pq.push(5);
    9. while (!pq.empty())
    10. {
    11. cout << pq.top() << " ";
    12. pq.pop();
    13. } cout << endl;
    14. }
    15. int main()
    16. {
    17. test111();
    18. }

    虽然可以运行正确,但是会报错:因为底层是vector,用的下标访问,下标一旦越界,就会报断言警告。

    最后发现是向下调整的问题,改一下:

    就可以正常运行不报错了:

  • 相关阅读:
    C++11新特性③ | 可变参数模板介绍
    下一代智能合约编程语言Move(二)
    云服务器免费体检
    python毕业设计作品基于django框架个人博客系统毕设成品(6)开题答辩PPT
    熟悉Redis6
    批量翻译文本文档终极指南
    CesiumJS 下载太慢了
    【正点原子STM32连载】 第六十四章 综合测试实验摘自【正点原子】MiniPro STM32H750 开发指南_V1.1
    jsp装修建材管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
    滑动窗口详解
  • 原文地址:https://blog.csdn.net/m0_65143871/article/details/133681442