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