堆是干啥用的?

- 它是树形结构,每个节点拥有一个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;
}

 

posted @ 2019-07-25 06:54  探险家_H  阅读(110)  评论(0编辑  收藏  举报