标签:
堆是一种完全二叉树,分为大根堆和小根堆,以大根堆为例:
大根堆满足性质:对于堆中的任意一个节点,其值在以该节点为根的子树中最大。
支持的操作:O(logn)的insert和O(logn)的pop.
(1)insert操作:将插入元素放到完全二叉树的最后一个节点之后的一个节点,然后从该节点开始向上不断维护堆的性质(若其父亲节点的值比其小,则交换,直到到达根节点或者父节点的值不比其小);
(2)pop操作:先将返回值(根节点的值)暂存,将最后一个节点的值赋给根节点,然后从根节点开始,向下维护堆的性质(若根节点值比其值最大的儿子的值小,那么与其交换,直到到达叶子节点或者其值不比值最大的儿子的值小),最后返回。
我的代码:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 #define MAXN 100005 7 8 struct bigRootHeap 9 { 10 int t[MAXN], sz; 11 void clear(){sz = 0;} 12 void push(int x) 13 { 14 t[++sz] = x; 15 int i = sz; 16 while(i!=1&&t[i/2]<t[i]) 17 { 18 swap(i/2, i); 19 i = i/2; 20 } 21 } 22 int pop() 23 { 24 if(sz==0) return 0; 25 int ans = t[1]; 26 t[1] = t[sz--]; 27 int i = 1; 28 while(2*i<=sz&&t[i]<t[bigSon(i)]) 29 { 30 int j = bigSon(i); 31 swap(i, j); 32 i = j; 33 } 34 return ans; 35 } 36 private: 37 void swap(int i, int j) 38 { 39 int tmp = t[i]; 40 t[i] = t[j]; 41 t[j] = tmp; 42 } 43 int bigSon(int i) 44 { 45 if(2*i+1>sz) return 2*i; 46 return t[2*i]>t[2*i+1]?2*i:2*i+1; 47 } 48 }heap; 49 50 int main() 51 { 52 int n; 53 while(cin>>n) 54 { 55 heap.clear(); 56 while(n--) 57 { 58 string op; 59 cin>>op; 60 if(op[0]==‘A‘) 61 { 62 int x; 63 cin>>x; 64 heap.push(x); 65 } 66 else cout<<heap.pop()<<endl; 67 } 68 } 69 return 0; 70 }
题目链接:http://hihocoder.com/problemset/problem/1105
标签:
原文地址:http://www.cnblogs.com/pczhou/p/4297920.html