首先来一发代码:
#include<bits/stdc++.h> using namespace std; const int N=1e6+5; int n,x,l,a[N]; void up(int x) { if (x==1)return; if (a[x]<a[x/2]) { swap(a[x],a[x/2]); up(x/2); } } void down(int x) { int i=x; if (x*2<=l&&a[x]>a[x*2])i=x*2; if (x*2<l&&a[i]>a[x*2+1])i=x*2+1; if (i!=x) { swap(a[i],a[x]); down(i); } } int main() { scanf("%d",&n); while (n--) { scanf("%d",&x); if (x==1) { scanf("%d",&a[++l]); up(l); } if (x==2)printf("%d\n",a[1]); if (x==3) { a[1]=a[l--]; down(1); } } }
然后来分析一下
堆书这样一中数据结构:每一个节点都比它的两个儿子小
那么根就是最小值
那么答案很好求
那么考虑假如一个点
我们把它连在最后,然后向上比较
当它比它的父亲的的时候停止
然否则一直往上交换
当要删掉一个节点的时候
网两个儿子进行比较,去除较小的儿子交换
然后继续往下比较
往上代码:
void up(int x) { if (x==1)return; if (a[x]<a[x/2]) { swap(a[x],a[x/2]); up(x/2); } }
往下代码:
void down(int x) { int i=x; if (x*2<=l&&a[x]>a[x*2])i=x*2; if (x*2<l&&a[i]>a[x*2+1])i=x*2+1; if (i!=x) { swap(a[i],a[x]); down(i); } }