平衡树
- 老旧的treap(无rank无select)
#include <iostream> #include <ctime> #include <cstdlib> using namespace std; #define NEW(d) new treap(d) struct treap { treap* ch[2]; int key, s; treap() : key(0), s(rand()) { ch[0] = ch[1] = NULL; } treap(int d) : key(d), s(rand()) { ch[0] = ch[1] = NULL; } bool operator< (const treap& a) { return s < a.s ? 1 : 0; } int cmp(int d) { if(key == d) return -1; return key > d ? 0 : 1; } }*root = NULL; typedef treap* tree; //左右旋,这里用的技巧是在lrj白书上看到的,旋转不多说,自己理解 void rot(tree& rt, int d) { tree k = rt-> ch[d^1]; rt-> ch[d^1] = k-> ch[d]; k-> ch[d] = rt; rt = k; } void insert(tree& rt, int d) { if(rt == NULL) rt = NEW(d); else { int p = (rt-> key > d ? 0: 1); insert(rt-> ch[p], d); if(rt < rt-> ch[p]) rot(rt, p^1); //先插入再旋转 } } void del(tree& rt, int d) { if(rt == NULL) return; int c = rt-> cmp(d); //如果找到节点 if(c == -1) { //如果有左右子女 if(rt-> ch[0] != NULL && rt-> ch[1] != NULL) { int p = (rt-> ch[1] < rt-> ch[0] ? 1 : 0); rot(rt, p); del(rt-> ch[p], d); } //如果没有子女或只有一个子女 else { tree t = rt; if(rt-> ch[0] == NULL) rt = rt-> ch[1]; else rt = rt-> ch[0]; delete t; } } //如果没找到节点 else del(rt-> ch[c], d); } tree search(int d) { tree ret = root; while(ret != NULL && ret-> key != d) if(ret-> key > d) ret = ret-> ch[0]; else ret = ret-> ch[1]; return ret; } tree max(){ if(root == NULL) return NULL; tree ret = root; while(ret-> ch[1]) ret = ret-> ch[1]; return ret; } tree min(){ if(root == NULL) return NULL; tree ret = root; while(ret-> ch[0]) ret = ret-> ch[0]; return ret; } void out(string str) { cout << str; } int main() { out("1: insert\n2: del\n3: search\n4: max\n5: min\n"); srand(time(NULL)); int c, t; tree a; while(cin >> c) { switch(c) { case 1: cin >> t; insert(root, t); break; case 2: cin >> t; del(root, t); break; case 3: cin >> t; if(search(t) == NULL) out("Not here\n"); else out("Is here!\n"); break; case 4: a = max(); if(a != NULL) cout << a-> key << endl; else out("Warn!\n"); break; case 5: a = min(); if(a != NULL) cout << a-> key << endl; else out("Warn!\n"); break; default: break; } } return 0; }
- 指针工程版treap(判断数据合法性的,包括rank和select)
#include <iostream> #include <ctime> #include <cstdlib> #include <string> using namespace std; #define R(t) t-> ch[1] #define L(t) t-> ch[0] #define C(t, c) t-> ch[c] #define S(t) t-> s #define W(t) t-> w #define K(t) t-> key #define PRE(t) R(t) = L(t) = null #define NEW new node struct Treap { struct node { int s, key, w; node* ch[2]; }; typedef node* tree; tree root, null; Treap() { null = NEW; PRE(null); root = null; } void pushup(tree t) { S(t) = S(R(t)) + S(L(t)) + 1; } void rot(tree& t, int d) { tree k = C(t, d^1); C(t, d^1) = C(k, d); pushup(t); C(k, d) = t; pushup(k); t = k; } void insert(tree& t, int k) { if(t == null) { t = NEW; K(t) = k; W(t) = rand(); S(t) = 1; PRE(t); return; } S(t)++; int d = k >= K(t); insert(C(t, d), k); if(W(t) < W(C(t, d))) rot(t, d^1); } void Del(tree& t, int k) { S(t)--; if(t == null) return; if(k == K(t)) { if(R(t) != null && L(t) != null) { int d = W(R(t)) < W(L(t)); rot(t, d); Del(C(t, d), k); } else { tree p = t; if(R(t) == null) t = L(t); else t = R(t); delete p; } } else Del(C(t, k >= K(t)), k); } tree select(tree t, int k) { //第k小的数,如果要求第k大,可以在调用调也可以将select函数中的L(t)与R(t)调换即可 if(k > S(t) || k <= 0 || t == null) return null; //if k > S(root) int s = S(L(t)) + 1; if(k == s) return t; else if(s > k) return select(L(t), k); else return select(R(t), k-s); } int Rank(tree t, int k) { if(t == null) return 0; //if search() == null int s = S(L(t)) + 1; if(k == K(t)) return s; if(k < K(t)) return Rank(L(t), k); else return Rank(R(t), k)+s; } void ins(int k) { insert(root, k); } void del(int k) { Del(root, k); } tree sel(int k) { return select(root, k); } int rank(int k) { return Rank(root, k); } tree search(int k) { tree t = root; while(t != null && k != K(t)) t = C(t, k >= K(t)); return t; } tree max() { tree t = root, q = null; while(t != null) q = t, t = R(t); return q; } tree min() { tree t = root, q = null; while(t != null) q = t, t = L(t); return q; } }treap; void out(string str) { cout << str; } int main() { out("1: insert\n2: del\n3: search\n4: max\n5: min\n6: select\n7: rank\n"); srand(time(NULL)); int c, t; Treap::tree a, null = treap.null; while(cin >> c) { switch(c) { case 1: cin >> t; treap.ins(t); break; case 2: cin >> t; treap.del(t); break; case 3: cin >> t; if(treap.search(t) == null) out("Not here\n"); else out("Is here!\n"); break; case 4: a = treap.max(); if(a != null) cout << K(a) << endl; else out("Warn!\n"); break; case 5: a = treap.min(); if(a != null) cout << K(a) << endl; else out("Warn!\n"); break; case 6: cin >> t; a = treap.sel(t); if(a != null) cout << K(a) << endl; else out("Warn!\n"); break; case 7: cin >> t; t = treap.rank(t); if(t != 0) cout << t << endl; else out("Warn!\n"); break; default: break; } } return 0; }
- OI简短指针版treap模版
#include #include #include using namespace std; #define K(t) t-> key #define W(t) t-> w #define C(t, d) t-> ch[d] #define R(t) t-> ch[1] #define L(t) t-> ch[0] #define S(t) t-> s #define PRE(t) R(t) = L(t) = null #define NEW(k) new node(k) #define pushup(t) S(t) = S(L(t)) + S(R(t)) + 1 struct Treap { struct node { int s, key, w; node* ch[2]; node(int k = 0) : s(1), key(k), w(rand()) { ch[0] = ch[1] = NULL; } }; typedef node* tree; tree root, null; Treap() { null = NEW(0); S(null) = 0; PRE(null); root = null; } void rot(tree& t, int d) { tree k = C(t, d^1); C(t, d^1) = C(k, d); pushup(t); C(k, d) = t; pushup(k); t = k; } void insert(tree& t, int k) { if(t == null) { t = NEW(k); PRE(t); return; } S(t)++; int p = k >= K(t); insert(C(t, p), k); if(W(t) < W(C(t, p))) rot(t, p^1); } void Del(tree& t, int k) { S(t)--; if(k == K(t)) { if(L(t) != null && R(t) != null) { int d = S(L(t)) > S(R(t)); rot(t, d); Del(C(t, d), k); } else { tree p = t; if(L(t) == null) t = R(t); else t = L(t); delete p; } } else Del(C(t, k >= K(t)), k); } int select(tree& t, int k) { int s = S(L(t)) + 1; if(s == k) return K(t); if(s > k) return select(L(t), k); else return select(R(t), k-s); } int Rank(tree& t, int k) { int s = S(L(t)) + 1; if(K(t) == k) return s; if(K(t) > k) return Rank(L(t), k); else return Rank(R(t), k)+s; } tree search(int k) { tree t = root; while(t != null && K(t) != k) t = C(t, k >= K(t)); return t; } int max() { tree t = root; while(R(t) != null) t = R(t); return K(t); } int min() { tree t = root; while(L(t) != null) t = L(t); return K(t); } void ins(int k) { insert(root, k); } void del(int k) { Del(root, k); } int sel(int k) { return select(root, k); } int rank(int k) { return Rank(root, k); } }T; int main() { srand(time(NULL)); int c, t; while(cin >> c) { switch(c) { case 1: cin >> t; T.ins(t); break; case 2: cin >> t; T.del(t); break; case 3: cin >> t; if(T.search(t) == T.null) cout << "Not here\n"; else cout << "Is here!\n"; break; case 4: cout << T.max() << endl; break; case 5: cout << T.min() << endl; break; case 6: cin >> t; cout << T.sel(t) << endl; break; case 7: cin >> t; cout << T.rank(t) << endl; break; default: break; } } return 0; }
博客地址:www.cnblogs.com/iwtwiioi 本文为博主原创文章,未经博主允许不得转载。一经发现,必将追究法律责任。