[置顶] c++实现的二叉堆::模板
相比各种树,各种dp,各种自动机,乱七八糟的哈希,这个东西真的简单
就一个仿树状数组::
每个节点的子节点是site<<1和site<<1|1(site*2,site*2+1),插入时维护一下最后一个节点(对于小顶堆,把小的往上传递即可。是不是像冒泡排序)
删除节点只要把最后一个节点变成之前的要替换的节点,然后用这个值取沉底(就相当于让别的冒泡上来,只不过这个沉底时有两条路可走,冒泡排序只有一条)沉底时选择两个子节点里小的替换就可以了。
冒泡排序大法好!!!
最麻烦的就是要在树中找这个点,找到就返回,其实要不是我经常爆内存,has完全可以用bfs,dfs的时间啊emmm
冒泡排序就不画图了哈!想找图这里有::https://jingyan.baidu.com/article/5225f26b057d5de6fa0908f3.html
#pragma once
template<class T>
class MinHeap {
private:
T * tree;
int size;
int len;
int cut(T value, int site) {
if (site > len) return 0;
if (tree[site] == value) {
if (site == len)--len;
tree[site] = tree[len--];
return site;
}
return cut(value, site << 1) + cut(value, site << 1 | 1);
}
bool has(T value, int site) {
if (tree[site] == value)return true;
if (site >= len)return false;
return has(value, site << 1) || has(value, site << 1 | 1);
}
void balance(int site) {
int l = site << 1;
int r = site << 1 | 1;
int c;
if (l > len) {
return;
}
else if (r > len) {
if (tree[site] > tree[l]) {
c = tree[l];
tree[l] = tree[site];
tree[site] = c;
}
}
else if (tree[l] > tree[r]) {
if (tree[site] > tree[r]) {
c = tree[r];
tree[r] = tree[site];
tree[site] = c;
balance(r);
}
}
else {
if (tree[site] > tree[l]) {
c = tree[l];
tree[l] = tree[site];
tree[site] = c;
balance(l);
}
}
}
public:
MinHeap(int size) {
this->size = size;
tree = new T[size + 1];
len = 0;
}
void insert(T value) {
tree[++len] = value;
int x = len;
int t = len / 2;
while (t != 0) {
if (value < tree[t]) {
tree[x] = tree[t];
tree[t] = value;
x = t;
}
else {
return;
}
t >>= 1;
}
}
void has(T value) {
if (has(value, 1)) {
printf("YES\n");
return;
}
printf("NO\n");
}
void cut(T value) {
if (has(value, 1)) {
balance(cut(value, 1));
}
else {
throw "No Such Node Please Check";
}
}
void print() {
for (int i = 1; i <= len; i++) {
printf("%d ", tree[i]);
}
}
};
浙公网安备 33010602011771号