二叉堆实现优先队列
#include <gtest/gtest.h>
#include <vector>
using namespace std;
// 实现最大堆
template <typename T>
class MyPQ {
 public:
  void push(T t) {
    v.emplace_back(t);
    swim(v.size() - 1);
  }
  T top() { return v[0]; }
  void pop() {
    swap(0, v.size() - 1);
    v.pop_back();
    sink(0);
  }
 private:
  vector<T> v;
  void swim(int i) {
    while (i > 0 && less(parent(i), i)) {
      swap(parent(i), i);
      i = parent(i);
    }
  }
  void sink(int i) {
    int n = v.size();
    while (left(i) < n) {
      int max = left(i);
      if (right(i) < n && less(max, right(i))) max = right(i);
      if (less(max, i)) break;
      swap(max, i);
      i = max;
    }
  }
  int parent(int i) { return (i - 1) / 2; }
  int left(int i) { return 2 * i + 1; }
  int right(int i) { return 2 * i + 2; };
  void swap(int i, int j) {
    auto temp = v[i];
    v[i] = v[j];
    v[j] = temp;
  }
  bool less(int i, int j) { return v[i] < v[j]; }
};
TEST(Algo, pq) {
  MyPQ<int> pq;
  pq.push(1);
  pq.push(3);
  pq.push(7);
  pq.push(5);
  pq.push(4);
  cout << pq.top() << endl;
  pq.pop();
  cout << pq.top() << endl;
}
总结
二叉堆就是一种完全二叉树,所以适合存储在数组中,而且二叉堆拥有一些特殊性质。
二叉堆的操作很简单,主要就是上浮和下沉,来维护堆的性质(堆有序)。
优先级队列是基于二叉堆实现的,主要操作是插入和删除。
插入是先插到最后,然后上浮到正确位置;
删除是把第一个元素 pq[0](最值)调换到最后再删除,然后把新的 pq[0] 下沉到正确位置。