void heapify(int o) //維護i號節點的堆性質 { while (1) { int ls = o << 1; int rs = o << 1 | 1; int mx = mh[o]; int mi = o; if (ls <= n1 && (mh[ls] < mx) ^ fl) { mx = mh[ls]; mi = ls; } if (rs <= n1 && (mh[rs] < mx) ^ fl) { mx = mh[rs]; mi = rs; } if (mi != o) { sw(mh[o], mh[mi]); o = mi; } else { break; } } }
for (int i = (n1 >> 1); i >= 1; --i) { heapify(i); }
void modify(int o, int v) //內部函數,將mh[o]改成v { if ((v < mh[o]) ^ fl) { mh[o] = v; while (o > 1 && (mh[o] < mh[o >> 1]) ^ fl) { sw(mh[o], mh[o >> 1]); o >>= 1; } } else { mh[o] = v; heapify(o); } }
應用:手寫優先隊列 luogu1168
ios
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #define INF 2147483647 using namespace std; int aa[100005], n; void sw(int& a, int& b) { int t = a; a = b; b = t; } struct minh { int mh[100005]; bool fl = false; //默認小根堆 int n1 = 0; void set(int f) //設置大小根堆 { bool r = f ^ fl; fl = f; if (r) //若是變化則更新堆 { for (int i = (n1 >> 1); i >= 1; --i) { heapify(i); } } } void heapify(int o) //維護i號節點的堆性質 { while (1) { int ls = o << 1; int rs = o << 1 | 1; int mx = mh[o]; int mi = o; if (ls <= n1 && (mh[ls] < mx) ^ fl) { mx = mh[ls]; mi = ls; } if (rs <= n1 && (mh[rs] < mx) ^ fl) { mx = mh[rs]; mi = rs; } if (mi != o) { sw(mh[o], mh[mi]); o = mi; } else { break; } } } void modify(int o, int v) //內部函數,將mh[o]改成v { if ((v < mh[o]) ^ fl) { mh[o] = v; while (o > 1 && (mh[o] < mh[o >> 1]) ^ fl) { sw(mh[o], mh[o >> 1]); o >>= 1; } } else { mh[o] = v; heapify(o); } } int top() //查詢 { return mh[1]; } void push(int v) //插入 { mh[++n1] = fl ? -INF : INF; modify(n1, v); } int pop() //帶返回值的pop { int v = -INF; if (n1) { v = mh[1]; mh[1] = mh[n1--]; heapify(1); } return v; } int size() //堆大小 { return n1; } } q1, q2; int main() { q1.n1 = q2.n1 = 0; q1.set(0); q2.set(1); scanf("%d", &n); int xx; scanf("%d", &xx); printf("%d\n", xx); q2.push(xx); for (int i = 2; i <= n; ++i) { scanf("%d", &xx); if (q1.size() == q2.size()) { int tmp = q1.top(); if (tmp < xx) { q2.push(tmp); q1.pop(); q1.push(xx); } else { q2.push(xx); } printf("%d\n", q2.top()); } else { int tmp = q2.top(); if (tmp > xx) { q1.push(tmp); q2.pop(); q2.push(xx); } else { q1.push(xx); } } } return 0; }