最大最小堆 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