堆的概念及实现

 

1.概述:

  堆的概念:堆是一种完全二叉树,其高度为log(n),可以用一维数组来实现。堆中存储的数据是局部有序的。可分为两种堆:最大顶堆和最小顶堆。

  最大顶堆:任意一个结点的值都大于等于其任意一个子结点的值。

  最小顶堆:任意一个结点的值都小于等于其任意一个子结点的值。

可以发现,堆的罗辑结构是树状结构,而存储结构是线性结构,因此,堆常用来实现优先队列。还可又来堆排序等。

 

2.基本操作:

  存储:显然,堆的元素可以保存在一维数组heap[]中,1表示根结点,结点k的父亲是k/2,左儿子是2×k,右儿子是2×k+1。

以最小顶堆为例:

  ① 向下调整:从根开始,选取当前结点 p 的较小的儿子结点;如果其值比 p 的值大,则调整停止。否则 p 和其儿子,继续调整。

  ② 向上调整:比较当前结点p和父节点,如果父节点的值比p小,则停止调整;否则交换父亲和p,继续向上调整。

  ③ 建立顶堆:从最后一个非终端结点即size/2处开始向下调整。

  ④ 删除堆顶:分为三步:1.直接删除根,2.用最后一个元素代替根,3.将堆向下调整。

  ⑤ 插入一个元素:分为两步:1.将元素添加到末尾,2.从末尾向上调整。

不难看出,基本操作其实就只有向下向上调整两个。

 

下面给出堆的类:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<queue>
 4 #define _Clr(x, y) memset(x, y, sizeof(x))
 5 #define INF 0x3f3f3f3f
 6 #define N 1010
 7 using namespace std;
 8 
 9 class HEAP
10 {
11     private:
12         int heap[N];
13         int size;
14     public:
15         HEAP(){size=0;_Clr(heap, 0);}
16         void Make(int x)
17         {
18             size++;
19             heap[size] = x;
20         }
21         void Down(int p)
22         {
23             int q = p<<1;
24             int a = heap[p];
25             while(q <= size)
26             {
27                 if(q<size && heap[q+1]<heap[q])
28                     q++;
29                 if(a <= heap[q]) break;
30                 else
31                 {
32                     heap[p] = heap[q];
33                     p = q;
34                     q = p<<1;
35                 }
36             }
37             heap[p] = a;
38         }
39         void Up(int p)
40         {
41             int q = p>>1;
42             int a = heap[p];
43             while(q>=1 && a<heap[q])
44             {
45                 heap[p] = heap[q];
46                 p = q;
47                 q = p>>1;
48             }
49             heap[p] = a;
50         }
51         int GetTop()
52         {
53             int t = heap[1];
54             heap[1] = heap[size--];
55             Down(1);
56             return t;
57         }
58         void Insert(int x)
59         {
60             heap[++size] = x;
61             Up(size);
62         }
63         void BuildMinHeap()
64         {
65             for(int i=size>>1; i>0; i--)
66                 Down(1);
67         }
68 };
69 int main()
70 {
71     return 0;
72 }
View Code

 

 

以poj2051为例:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<queue>
 4 #define _Clr(x, y) memset(x, y, sizeof(x))
 5 #define INF 0x3f3f3f3f
 6 #define N 1010
 7 using namespace std;
 8 
 9 class HEAP
10 {
11     private:
12         struct Node
13         {
14             int id;
15             int p;
16             int t;
17         }heap[N];
18         int size;
19     public:
20         HEAP(){size=0; _Clr(heap, 0);}
21         void Make(int id, int p, int i)
22         {
23             size=i;
24             heap[size].id = id;
25             heap[size].p = heap[size].t = p;
26         }
27         int GetTop()
28         {
29             int t = heap[1].id;
30             heap[1].t += heap[1].p;
31             Down(1);
32             return t;
33         }
34         void Down(int p)
35         {
36             int q = 2*p;
37             Node a = heap[p];
38             while(q<=size)
39             {
40                 if(q<size)
41                 {
42                     if(heap[q+1].t < heap[q].t)
43                         q++;
44                     else if(heap[q+1].t==heap[q].t && heap[q+1].id < heap[q].id)
45                         q++;
46                 }
47                 if(a.t<heap[q].t || (a.t==heap[q].t && a.id<heap[q].id))
48                     break;
49                 else
50                 {
51                     heap[p] = heap[q];
52                     p = q;
53                     q = 2*p;
54                 }
55             }
56             heap[p] = a;
57         }
58         void BuildMinHeap()
59         {
60             for(int i=size/2; i>0; i--)
61                 Down(i);
62         }
63         void Print()
64         {
65             for(int i=1; i<=size; i++)
66                 printf("%d ", heap[i].id);
67             puts("");
68         }
69 }A;
70 
71 int main()
72 {
73     char str[10];
74     int i=1, id, p;
75     while(~scanf("%s", str) && strcmp(str, "#"))
76     {
77         scanf("%d%d", &id, &p);
78         A.Make(id, p, i);
79         i++;
80     }
81     A.BuildMinHeap();
82     int k;
83     scanf("%d", &k);
84     for(int i=0; i<k; i++)
85         printf("%d\n",A.GetTop());
86     return 0;
87 }
View Code

 

posted @ 2015-04-09 15:24  无道圣君  阅读(688)  评论(0编辑  收藏  举报