平衡树

  • 老旧的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
    2: del
    3: search
    4: max
    5: min
    ");
    	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
    ");
    				else out("Is here!
    ");
    				break;
    		case 4: a = max();
    				if(a != NULL) cout << a-> key << endl;
    				else out("Warn!
    ");
    				break;
    		case 5: a = min();
    				if(a != NULL) cout << a-> key << endl;
    				else out("Warn!
    ");
    				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
    2: del
    3: search
    4: max
    5: min
    6: select
    7: rank
    ");
    	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
    ");
    				else out("Is here!
    ");
    				break;
    		case 4: a = treap.max();
    				if(a != null) cout << K(a) << endl;
    				else out("Warn!
    ");
    				break;
    		case 5: a = treap.min();
    				if(a != null) cout << K(a) << endl;
    				else out("Warn!
    ");
    				break;
    		case 6: cin >> t;
    				a = treap.sel(t);
    				if(a != null) cout << K(a) << endl;
    				else out("Warn!
    ");
    				break;
    		case 7: cin >> t;
    				t = treap.rank(t);
    				if(t != 0) cout << t << endl;
    				else out("Warn!
    ");
    				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
";
				else cout << "Is here!
";
				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;
}

  

原文地址:https://www.cnblogs.com/iwtwiioi/p/3536845.html