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

    ((^ 0.0 ^)    )~

    堆是一个完全二叉树,对于小根堆,所有父节点<=子节点,下标就和线段树是一样的

    在STL里就是优先队列

    只有堆顶元素可以操作(询问或弹出)。

    加入新元素时x,heap[++size] = x,下标t=size;

    每次比较它和父节点(t/2)的大小,如果它较小就swap。

    删除堆顶元素时,用最后一个元素heap[size--]覆盖heap[1],下标t=1;

    每次比较它和左右两个儿子的大小,和较小的swap。

    注意:

    • 下标t的值不能大于堆的size;
    • 我一开始是这么写的:
    • void del() {
          swap(heap[1],heap[cnt--]);
          int t = 1;
          while(t*2 <= cnt && (heap[t] > heap[t*2] || heap[t] > heap[t*2+1])) {
          if(heap[t*2+1] < heap[t*2] && t*2+1 <= cnt) {    
                  swap(heap[t],heap[t*2+1]);
                  t = t*2+1;
              } else {
                  swap(heap[t],heap[t*2]);
                  t *= 2;
              }
          }
      }
      swap(heap[1],heap[cnt--])改为heap[1] = heap[cnt--]就对了
    • 如果把最小的数x放到了下面,将最后一个数y从堆顶下移,判断到x的父亲时,一定有x<=y。因为判断是否交换时的条件是左右儿子有一个>y就继续循环,虽然此时判断x的下标>size,但是会默认和另一个儿子交换。
    • 如果最后一个值是空的时(为0)就更会翻车了!所以边界条件还是分别判断,这样swap也没问题啦。

    代码如下

    #include<cstdio>
    #include<iostream>
    
    using namespace std;
    const int maxn = 1000005;
    int heap[maxn],n,a,b,cnt;
    
    void insert(int x) {
        heap[++cnt] = x;
        int t = cnt;
        while(heap[t] < heap[t/2]) {
            swap(heap[t],heap[t/2]);
            t/=2;
        }
    }
    
    void del() {
        heap[1] = heap[cnt--];
        int t = 1;
        while((t*2 <= cnt && heap[t] > heap[t*2]) || (t*2+1 <= cnt && heap[t] > heap[t*2+1])) {
            if(heap[t*2+1] < heap[t*2] && t*2+1 <= cnt) {
                swap(heap[t],heap[t*2+1]);
                t = t*2+1;
            } else {
                swap(heap[t],heap[t*2]);
                t *= 2;
            }
        }
    }
    
    int main() {
        scanf("%d",&n);
        for(int i = 1; i <= n; i++) {
            scanf("%d",&a);
            if(a == 1) {
                scanf("%d",&b);
                insert(b);
            }
            if(a == 2) {
                if(cnt)printf("%d
    ",heap[1]);
            }
            if(a == 3) {
                del();
            }
        }
        return 0;
    }
  • 相关阅读:
    JS调试工具
    什么是Web Service?
    win7怎么安装消息队列 MSMQ
    死锁产生的原因及四个必要条件
    项目管理模式之如何去除SVN标记
    AJAX中的请求方式以及同步异步的区别
    敏捷软件开发模型--SCRUM
    堆和栈
    UI产品设计流程中的14个要点
    Android中dp和px之间进行转换
  • 原文地址:https://www.cnblogs.com/mogeko/p/10297024.html
Copyright © 2011-2022 走看看