SBT 模板

来源:互联网 发布:mysql事务原理 编辑:程序博客网 时间:2024/05/20 07:50

贴一发SBT的模板............慢慢熟悉

学习请戳这:http://blog.csdn.net/acceptedxukai/article/details/6921334


#include <iostream>#include <algorithm>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <string>#include <vector>#include <set>#include <queue>#include <stack>#include <climits>//形如INT_MAX一类的#define MAX 111111#define INF 0x7FFFFFFF#define REP(i,s,t) for(int i=(s);i<=(t);++i)#define ll long long#define mem(a,b) memset(a,b,sizeof(a))#define mp(a,b) make_pair(a,b)#define L(x) x<<1#define R(x) x<<1|1# define eps 1e-5//#pragma comment(linker, "/STACK:36777216") ///传说中的外挂using namespace std;struct sbt {    int l,r,s,key;} tr[MAX];int top , root;void left_rot(int &x) {    int y = tr[x].r;    tr[x].r = tr[y].l;    tr[y].l = x;    tr[y].s = tr[x].s; //转上去的节点数量为先前此处节点的size    tr[x].s = tr[tr[x].l].s + tr[tr[x].r].s + 1;    x = y;}void right_rot(int &x) {    int y = tr[x].l;    tr[x].l = tr[y].r;    tr[y].r = x;    tr[y].s = tr[x].s;    tr[x].s = tr[tr[x].l].s + tr[tr[x].r].s + 1;    x = y;}void maintain(int &x,bool flag) {    if(flag == 0) { //左边        if(tr[tr[tr[x].l].l].s > tr[tr[x].r].s) {//左孩子左子树size大于右孩子size            right_rot(x);        } else if(tr[tr[tr[x].l].r].s > tr[tr[x].r].s) {//左孩子右子树size大于右孩子size            left_rot(tr[x].l);            right_rot(x);        } else return ;    } else { //右边        if(tr[tr[tr[x].r].r].s > tr[tr[x].l].s) { //右孩子的右子树大于左孩子            left_rot(x);        } else if(tr[tr[tr[x].r].l].s > tr[tr[x].l].s) { //右孩子的左子树大于左孩子            right_rot(tr[x].r);            left_rot(x);        } else return ;    }    maintain(tr[x].l,0);    maintain(tr[x].r,1);}void insert(int &x,int key) {    if(x == 0) { //空节点        x = ++ top;        tr[x].l = tr[x].r = 0;        tr[x].s = 1;        tr[x].key = key;    } else {        tr[x].s ++;        if(key < tr[x].key) insert(tr[x].l,key);        else insert(tr[x].r,key);        maintain(x,key >= tr[x].key);    }}int del(int &p,int w) {    if (tr[p].key==w || (tr[p].l == 0 && w < tr[p].key) || (tr[p].r == 0 && w > tr[p].key)) {        int delnum = tr[p].key;        if (tr[p].l == 0 || tr[p].r == 0) p = tr[p].l + tr[p].r;        else tr[p].key=del(tr[p].l,INF);        return delnum;    }    if (w < tr[p].key) return del(tr[p].l,w);    else return del(tr[p].r,w);}int remove(int &x,int key) {    int k;    tr[x].s --;    if(key == tr[x].key || (key < tr[x].key && tr[x].l == 0) || (key > tr[x].key && tr[x].r == 0)) {        k = tr[x].key;        if(tr[x].l && tr[x].r) {            tr[x].key = remove(tr[x].l,tr[x].key + 1);        } else {            x = tr[x].l + tr[x].r;        }    } else if(key > tr[x].key) {        k = remove(tr[x].r,key);    } else if(key < tr[x].key) {        k = remove(tr[x].l,key);    }    return k;}int getmin() { //二叉搜索树找最小值    int x;    for(x = root; tr[x].l; x = tr[x].l) ;    return tr[x].key;}int getmax() {    int x;    for(x = root ; tr[x].r; x = tr[x].r) ;    return tr[x].key;}int pred(int &x,int y,int key)//前驱 小于{    if(x == 0) return y;    if(tr[x].key < key)//加上等号,就是小于等于        return pred(tr[x].r,x,key);    else return pred(tr[x].l,y,key);}//pred(root,0,key)int succ(int &x,int y,int key) { //后继 大于    if(x == 0) return y;    if(tr[x].key > key)        return succ(tr[x].l,x,key);    else return succ(tr[x].r,y,key);}int select(int &x,int k) { //求第k小数    int r = tr[tr[x].l].s + 1;    if(r == k) return tr[x].key;    else if(r < k) return select(tr[x].r,k - r);    else return select(tr[x].l,k);}int rank(int &x,int key) { //求第K小数的逆运算    if(key < tr[x].key) return rank(tr[x].l,key);    else if(key > tr[x].key) return rank(tr[x].r,key);    else return tr[tr[x].l].s + 1;}void inorder(int &x) {    if(x == 0) return;    else {        inorder(tr[x].l);        cout<< x <<" "<< tr[x].key << " " <<tr[x].s << " " <<tr[tr[x].l].key << " " << tr[tr[x].r].key << endl;        inorder(tr[x].r);    }}


原创粉丝点击