• 堆的概念及实现


    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
    ",A.GetTop());
    86     return 0;
    87 }
    View Code
  • 相关阅读:
    正则表达式
    浅谈xss攻击
    四舍五入[银行家算法]
    POJ-2442-Sequence(二叉堆)
    Spring MVC 启动报错
    WebMagic 抓取图片并保存至本地
    spring 定时任务
    jquery validate 自定义校验方法
    位图
    二叉树(线索化)
  • 原文地址:https://www.cnblogs.com/khan724/p/4409785.html
Copyright © 2020-2023  润新知