最大最小堆 priority_queue


所有的数据结构书中都有关于堆的详细介绍,向堆中插入、删除元素时间复杂度都是O(lgN),N为堆中元素的个数,而获取最小key值(小根堆)的复杂度为O(1)。

堆是一个完全二叉树,基本存储方式是一个数组。

 

优先队列是一种比较常用的结构,虽然被称为队列,但却不是队列。

 

  • C++ STL默认的priority_queue是将优先级最大的放在队列最前面,也即是最大堆。那么如何实现最小堆呢?

假设有如下一个struct:

struct Node { int value; int idx; Node (int v, int i): value(v), idx(i) {} friend bool operator < (const struct Node &n1, const struct Node &n2) ; }; inline bool operator < (const struct Node &n1, const struct Node &n2) { return n1.value < n2.value; } priority_queue<Node> pq; // 此时pq为最大堆
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

如果需要最大堆,则需要如下实现:

struct Node { int value; int idx; Node (int v, int i): value(v), idx(i) {} friend bool operator > (const struct Node &n1, const struct Node &n2) ; }; inline bool operator > (const struct Node &n1, const struct Node &n2) { return n1.value > n2.value; } priority_queue<Node, vector<Node>, greater<Node> > pq; // 此时greater会调用 > 方法来确认Node的顺序,此时pq是最小堆
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

其他解决

当然,还有些比较小的较为hack的手段进行。比如要构造一个int类型的最小堆:

priority_queue<int> pq; // pq.push( -1 * v1) ; // pq.push( -1 * v2) ; // pq.push( -1 * v3) ; // 分别是插入v1, v2, v3变量的相反数,那么pq其实也就变相成为了最小堆,只是每次从pq取值后,要再次乘以-1即可
  • 1
  • 2
  • 3
  • 4

此外,再贴一份网上的某

 

#include <iostream>
#include <queue>


using namespace std;


struct node{
  int idx;
  int key;
  node(int a=0, int b=0):idx(a), key(b){}
};

struct cmp{
  bool operator()(node a, node b){
    return a.key > b.key;
  }
};
int main(){
  
  priority_queue<node, vector<node>, cmp> q;
  
  int i;
  for(i=0;i<10;++i){
    q.push(node(i, i));
  }

  while(!q.empty()){
    cout<<q.top().key<<endl;
    q.pop();
  }
  return 0;
}

  


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM