hihocoder1105 堆

堆是一种完全二叉树,分为大根堆和小根堆,以大根堆为例:

大根堆满足性质:对于堆中的任意一个节点,其值在以该节点为根的子树中最大。

支持的操作: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

posted @ 2015-02-23 10:53  __brthls  阅读(200)  评论(0编辑  收藏  举报