zoukankan      html  css  js  c++  java
  • Luogu P3378 【模板】堆

    题目描述

    如题,初始小根堆为空,我们需要支持以下3种操作:

    操作1: 1 x 表示将x插入到堆中

    操作2: 2 输出该小根堆内的最小数

    操作3: 3 删除该小根堆内的最小数

    输入输出格式

    输入格式:

    第一行包含一个整数N,表示操作的个数

    接下来N行,每行包含1个或2个正整数,表示三种操作,格式如下:

    操作1: 1 x

    操作2: 2

    操作3: 3

    输出格式:

    包含若干行正整数,每行依次对应一个操作2的结果。

    输入输出样例

    输入样例#1:

    5
    1 2
    1 5
    2
    3
    2

    输出样例#1:

    2
    5

    说明

    时空限制:1000ms,128M

    数据规模:

    对于30%的数据:N<=15

    对于70%的数据:N<=10000

    对于100%的数据:N<=1000000(注意是6个0。。。不过不要害怕,经过编者实测,堆是可以AC的)

    样例说明:

    故输出为2、5

    Solution

    这道题需我们进行4步操作:插入、调整、查询和删除。

    插入:

    在插入时,只需将插入的数放在堆的最后一位,然后自下往上进行调整。

    调整:

    1.自下往上调整:

    调整时,我们将当前节点与它的父亲节点相比,若小于父亲节点则这两点交换,并将它的父亲节点标为当前节点,直到达到根节点或大于父亲节点为止。这样,我们就能保证每一个节点都能大于其父亲节点,从而成功维护小根堆。

    2.自上往下调整:

    调整时我们将当前节点与它的两个孩子节点相比(若只有一个孩子节点则只与那个孩子节点比较),若大于较小的那个孩子节点则这两点交换,并将该孩子节点标为当前节点,直到到达叶子结点或小于较小的那个孩子节点为止。这样,选孩子节点中较小的那个与当前节点比较,若交换后它也比另一个孩子节点小,我们就能保证每一个节点都能大于其父亲节点,从而成功维护小根堆。

    查询:

    只需输出堆中的第一个元素(即根节点)就行啦!

    删除:

    删除时,只需将堆的最后一个节点的值赋给第一个节点,覆盖掉原来第一个节点的值,并将堆的节点数-1,代表删除堆的最后一个节点。


    pascal代码如下:

    var n,m,i,j,k,l,min:longint;
    a:array[0..2000000]of longint;//堆
    begin
      readln(n);
      for m:=1 to n do
      begin
        read(l);
        if l=1 then//插入操作
        begin
          inc(k);
          read(a[k]);
          i:=k;
          while a[i]<a[i div 2] do//自下往上调整
          begin
            j:=a[i];
            a[i]:=a[i div 2];
            a[i div 2]:=j;
            i:=i div 2;
          end;
        end
        else
        if l=2 then//查询操作
        writeln(a[1])
        else
        begin//删除操作
          a[1]:=a[k];
          dec(k);
          i:=1;
          if (a[i*2]<a[i*2+1])or(i*2=k) then//比较两个孩子节点的值,取小的那一个与该节点比较
          min:=i*2
          else
          min:=i*2+1;
          while (min<=k)and(a[i]>a[min]) do//自上往下调整
          begin
            j:=a[i];
            a[i]:=a[min];
            a[min]:=j;
            i:=min;
            if (a[i*2]<a[i*2+1])or(i*2=k) then
            min:=i*2
            else
            min:=i*2+1;
          end;
        end;
      end;
    end.
  • 相关阅读:
    TClientDataSet[7]: 辨析 Field、FieldDef、Fields、FieldDefs、FieldList、FieldDefList
    TClientDataSet[11]: 分组统计
    TClientDataSet[14]: 测试 FindFirst、FindNext、FindLast、FindPrior、Found
    TClientDataSet[9]: 计算字段和 State
    这两天的收获
    又去北京
    关于博客园融资的想法
    《别为小事抓狂》读书笔记
    下周将去北京寻找投资
    服务器搬迁预告
  • 原文地址:https://www.cnblogs.com/qbwhtc/p/7465179.html
Copyright © 2011-2022 走看看