[置顶] 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]); } } };