zoukankan      html  css  js  c++  java
  • 堆是干啥用的?

    - 它是树形结构,每个节点拥有一个key

    - 父亲节点的key必大于两个儿子节点

    堆的查询

    堆只能查询根节点

    返回根节点的value(key)

    堆的插入

    给定一个key值,如何将它插入堆?

    - 核心思想:修复

    - 直接将他摆在堆的末尾,然后修复这个堆

    向上修复

    如果它的key值比父亲大,交换它和父亲,递归执行

    直到它的key值比父亲小,修复完毕

    堆的删除

    堆的删除仅限于删除根节点

    如何删除一个根节点呢?

    - 核心思想:修复

    - 直接把它和末尾的元素交换,然后直接删掉它

    - 修复

    向下修复

    子节点选较大并且比自身大,交换,递归执行

    /*
        大根堆
        by lhw
    */ 
    
    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 1000001;
    
    int n;
    int a[N];
    
    int ls(int x){ return x << 1; }
    int rs(int x){ return x << 1 | 1; }
    int da(int x){ return x >> 1; }
    
    struct heap{
        int w[N];
        int tot;
        
        int top(){ return w[1]; }
        
        void repair_up(int x){
            if(x == 1) return ;
            if(w[x] > w[da(x)])
                swap(w[x], w[da(x)]), repair_up(da(x));
        }
        
        void repair_down(int x){
            int tar = w[ls(x)] > w[rs(x)] ? ls(x) : rs(x);
            if(w[tar] > w[x])
                swap(w[tar], w[x]), repair_down(tar);
        }
        
        void push(int key){
            w[++tot] = key;
            repair_up(tot);
        }
        
        void del(){
            swap(w[1], w[tot]);
            w[tot] = 0;
            repair_down(1);
        }
        
    };
    
    heap h;
    
    int main(){
        cin >> n;
        for(int i = 1, x; i <= n; ++i) cin >> x, h.push(x);
        for(int i = 1; i <= n; ++i){
            a[i] = h.top();
            h.del();
        }
        for(int i = n; i >= 1; --i) cout << a[i] << " ";
        return 0;
    }
  • 相关阅读:
    SQL之CASE WHEN用法详解
    MySQL笔记汇总
    Linux常用命令
    TCP/IP速记
    数据结构和算法速记
    多线程相关概念
    线程安全&Java内存模型
    线程通讯wait&notify
    创建多线程的4种方式
    重写ThreadPoolTaskExecutor
  • 原文地址:https://www.cnblogs.com/Adventurer-H/p/11241889.html
Copyright © 2011-2022 走看看