平衡树

  • 老旧的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;

}

  

你可能感兴趣的:(树)