C++STL手写版

手写STL,卡常专用。

node为变量类型,可以自由定义,以下不再赘述。

1、stack(栈)

  开一个数组,和一个top指针,压栈时++,弹栈时--即可。

struct stack{
    int tp;node st[N];
    node top(){return st[tp];}
    void push(node x){st[++tp]=x;}
    void pop(){--tp;}
    bool empty(){return !tp;}
    void size(){return tp;}
    void clear(){tp=0;}
}s;

 

2、queue(循环队列)

  用两个指针,记录队头和队尾,达到两端时特判即可。

struct queue{
    int l,r,cnt;node qu[N];
    node front(){return qu[l];}
    void ne(int &x){++x;if(x==N) x=1;}
    void push(node x){ne(r);qu[r]=x;++cnt;}
    void pop(){ne(l);--cnt;}
    bool empty(){return !cnt;}
    void size(){return cnt;}
    void clear(){r=cnt=0,l=1;}
}q;

 

3、deque(双端队列)

  和队列类似。

struct deque{
    int l,r,cnt;node qu[N];
    void init(){r=cnt=0,l=1;}
    node front(){return qu[l];}
    node back(){return qu[r];}
    void ne(int &x){++x;if(x==N) x=1;}
    void la(int &x){--x;if(!x) x=N-1;}
    void push_front(node x){la(l);qu[l]=x;++cnt;}
    void push_back(node x){ne(r);qu[r]=x;++cnt;}
    void pop_front(){ne(l);--cnt;}
    void pop_back(){la(r);--cnt;}
    bool empty(){return !cnt;}
    void size(){return cnt;}
    void clear(){r=cnt=0,l=1;}
}q;

 

4、priority_queue(优先队列)

  具有强大的功能,可以删除任意一个元素。

  使用时在node内部重载"<"号,删除元素传该元素的id。

  %%%remarkable的手写堆是假的,通常情况下删除堆中元素时并不知道它在堆中的下标,而是知道id。

  id值可以在node里维护,就对id开一个互逆数组,同时交换即可。

struct priority_queue{
    int cnt,p[N];node heap[N];
    void up(int x){
        while(x>1&&heap[x>>1]<heap[x]){
            swap(p[heap[x>>1].id],p[heap[x].id]);
            swap(heap[x>>1],heap[x]);
            x>>=1;
        }
    }
    void down(int x){
        int y=x<<1;
        while(y<=cnt){
            if(y<cnt&&heap[y]<heap[y|1]) y|=1;
            if(heap[x]<heap[y]){
                swap(p[heap[x].id],p[heap[y].id]);
                swap(heap[x],heap[y]);
                x=y;y=x<<1;
            }
            else break;
        }
    }
    int size(){return cnt;}
    bool empty(){return !cnt;}
    void push(node x){heap[++cnt]=x;p[x.id]=cnt;up(cnt);}
    node top(){return heap[1];}
    void pop(){
        swap(p[heap[1].id],p[heap[cnt].id]);
        swap(heap[1],heap[cnt]);
        p[heap[cnt].id]=0;cnt--;
        if(cnt) down(1);
    }
    void remove(int x){
        x=p[x];
        swap(p[heap[x].id],p[heap[cnt].id]);
        swap(heap[x],heap[cnt]);
        p[heap[cnt].id]=0;cnt--;
        if(x<=cnt){up(x);down(x);}
    }
    void clear(){cnt=0;}
}q;

 

5、bitset(多位二进制数)

  ct数组需预处理,表示每个数中1的个数。

struct bitset{
    unsigned long long a[N];
    const unsigned long long m=65535;
    void clear(){memset(a,0,sizeof(a));}
    void set(){for(int i=0;i<N;i++) a[i]=m+(m<<16)+(m<<32)+(m<<48);}
    void reset(){clean();}
    void flip(){for(int i=0;i<N;i++) a[i]^=(m+(m<<16)+(m<<32)+(m<<48));}
    void set(int x,int y){
        if(y==1) a[x/64]|=(unsigned long long)1<<(x&63);
        else if((a[x/64]>>(x&63))&1) a[x/64]^=(unsigned long long)1<<(x&63);
    }    
    void reset(int x){set(x,0);}
    void flip(int x){
        a[x/64]^=(unsigned long long)1<<(x&63);
    }
    friend bitset operator | (const bitset &x,const bitset &y){
        bitset ans;ans.clear();
        for(int i=0;i<N;i++) ans.a[i]=x.a[i]^y.a[i];
        return ans;
    }
    friend bitset operator & (const bitset &x,const bitset &y){
        bitset ans;ans.clear();
        for(int i=0;i<N;i++) ans.a[i]=x.a[i]^y.a[i];
        return ans;
    }
    friend bitset operator ^ (const bitset &x,const bitset &y){
        bitset ans;ans.clear();
        for(int i=0;i<N;i++) ans.a[i]=x.a[i]^y.a[i];
        return ans;
    }
    friend void operator |= (bitset &x,const bitset &y){
        for(int i=0;i<N;i++) x.a[i]|=y.a[i];
        return ;
    }
    friend void operator &= (bitset &x,const bitset &y){
        for(int i=0;i<N;i++) x.a[i]&=y.a[i];
        return ;
    }
    friend void operator ^= (bitset &x,const bitset &y){
        for(int i=0;i<N;i++) x.a[i]^=y.a[i];
        return ;
    }
    int count(){
        int cnt=0;
        for(int i=0;i<N;i++) cnt+=ct[a[i]&m]+ct[(a[i]>>16)&m]+ct[(a[i]>>32)&m]+ct[(a[i]>>48)&m];
        return cnt;
    }
    bool any(){return count();}
    bool none(){return !count();}
}b;

 

6、set/map(红黑树)

 

C++STL手写版

  1 #include<iostream>
  2 #include<cstdio>
  3 #define Red true
  4 #define Black false
  5 using namespace std;
  6 const int N=400005;
  7 int n;
  8 struct node{
  9     int key,si,we,co;
 10     node *f,*ch[2];
 11     void fill(int _key,int _co,int _we,node *now){//初始化节点信息
 12         this->key=_key;this->co=_co;
 13         this->si=this->we=_we; 
 14         this->f=this->ch[0]=this->ch[1]=now;
 15     }
 16     void pushup(){//上传更新
 17         this->si=this->ch[0]->si+this->ch[1]->si+this->we;
 18     }
 19     void pushdown(){//也是上传更新
 20         for(node *now=this;now->si;now=now->f) now->si--;
 21     }
 22     int getpos(int x){//判断向左或向右走
 23         return (this->key==x)?-1:(x>this->key);
 24     }
 25 }I;
 26 struct Red_Black_Tree{
 27     int cnt;
 28     node *rt,*nul;//红黑树没有空指针,所有空指针指向nul
 29     node pool[N],*tail,*re[N];//内存池
 30     void init(){//初始化
 31         cnt=0;tail=&pool[cnt];nul=tail++;
 32         nul->fill(0,Black,0,NULL);rt=nul;
 33     }
 34     node *New(int key){//新建节点
 35         node *now=nul;
 36         if(!cnt) now=tail++;
 37         else now=re[--cnt];
 38         now->fill(key,Red,1,nul);//新节点为红色
 39         return now;
 40     }
 41     void rotate(node *now,int pos){//旋转操作
 42         node *c=now->ch[pos^1];
 43         now->ch[pos^1]=c->ch[pos];
 44         if(c->ch[pos]->si) c->ch[pos]->f=now;
 45         c->f=now->f;
 46         if(!now->f->si) rt=c;//旋到根
 47         else now->f->ch[now->f->ch[0]!=now]=c;
 48         c->ch[pos]=now;now->f=c;c->si=now->si;
 49         now->pushup();
 50     }
 51     void insert_transfrom(node *now){//插入调整
 52         for(;now->f->co;){//当父亲为红色,不合法,需要调整
 53             node *fa=now->f,*gr=fa->f;
 54             int pos=fa==gr->ch[0];node *un=gr->ch[pos];
 55             if(un->co){//叔叔是红色,父亲和叔叔同时染成黑色
 56                 fa->co=un->co=Black;
 57                 gr->co=Red;now=gr;
 58             }
 59             else if(now==fa->ch[pos]) rotate(now=fa,pos^1);//父亲不是根
 60             else{
 61                 gr->co=Red;fa->co=Black;rotate(gr,pos);
 62             }
 63         }
 64         rt->co=Black;//根必须是黑色
 65     }
 66     void remove_transfrom(node *now){//删除调节
 67         for(;now!=rt&&!now->co;){
 68             int pos=now==now->f->ch[0];
 69             node *fa=now->f,*br=fa->ch[pos];
 70             if(br->co){//调节颜色一致
 71                 br->co=Black;fa->co=Red;
 72                 rotate(now->f,pos^1);
 73                 br=fa->ch[pos];
 74             }
 75             else if(!br->ch[0]->co&&!br->ch[1]->co){//兄弟的两个儿子都是黑色
 76                 br->co=Red;now=fa;//兄弟染成红色
 77             }
 78             else{
 79                 if(!br->ch[pos]->co){//保持路径上黑色节点数相同
 80                     br->ch[pos^1]->co=Black;br->co=Red;
 81                     rotate(br,pos);br=fa->ch[pos];
 82                 }
 83                 br->co=fa->co;br->ch[pos]->co=fa->co=Black;
 84                 rotate(fa,pos^1);break;
 85             }
 86         }
 87         now->co=Black;
 88     }
 89     void insert(int key){//插入节点
 90         node *now=rt,*fa=nul;int pos;
 91         for(;now->si;now=now->ch[pos]){
 92             now->si++;fa=now;
 93             pos=now->getpos(key);
 94             if(pos==-1){//找到对应值
 95                 now->we++;return;
 96             }
 97         }
 98         now=New(key);//找到位置,插入节点
 99         if(fa->si) fa->ch[key>fa->key]=now;
100         else rt=now;
101         now->f=fa;insert_transfrom(now);
102     }
103     node *find(node *now,int key){//查找位置
104         for(;now->si&&now->key!=key;now=now->ch[now->key<key]);
105         return now;
106     }
107     void remove(int key){
108         node *res=find(rt,key);
109         if(!res->si) return;//没有找到
110         if(res->we>1){//有多个,只删除一个
111             res->we--;res->pushdown();return;
112         }
113         node *fa=res,*now=nul;
114         if(res->ch[0]->si&&res->ch[1]->si){//有两个儿子,找节点替代自己
115             for(fa=res->ch[1];fa->ch[0]->si;fa=fa->ch[0]);//找后继
116         }
117         now=fa->ch[!fa->ch[0]->si];now->f=fa->f;
118         if(!fa->f->si) rt=now;//当前点是根
119         else fa->f->ch[fa->f->ch[1]==fa]=now;
120         if(res!=fa){
121             res->key=fa->key;res->we=fa->we;
122         }
123         fa->f->pushdown();
124         for(node *st=fa->f;fa->we>1&&st->si&&st!=res;st->si-=fa->we-1,st=st->f);
125         if(!fa->co) remove_transfrom(now);
126         re[cnt++]=fa;//回收内存
127     }
128     int rnk(int key){//查排名
129         int res,ans=0;
130         for(node *now=rt;now->si;){
131             res=now->ch[0]->si;
132             if(now->key==key) break;
133             else if(now->key>key) now=now->ch[0];
134             else{
135                 ans+=res+now->we;now=now->ch[1];
136             }
137         }
138         return ans+res+1;
139     }
140     int kth(int k){//查数
141         int res;node *now=rt;
142         for(;now->si;){
143             res=now->ch[0]->si;
144             if(k<=res) now=now->ch[0];
145             else if(res+1<=k&&k<=res+now->we) break;
146             else{
147                 k-=res+now->we;now=now->ch[1];
148             }
149         }
150         return now->key;
151     }
152     int pre(int key){//前驱
153         int res=0;
154         for(node *now=rt;now->si;){
155             if(now->key<key){
156                 res=now->key;now=now->ch[1];
157             }
158             else now=now->ch[0];
159         }
160         return res;
161     }
162     int nxt(int key){//后继
163         int res=0;
164         for(node *now=rt;now->si;){
165             if(now->key>key){
166                 res=now->key;now=now->ch[0];
167             }
168             else now=now->ch[1];
169         }
170         return res;
171     }
172 }rbt;
173 int main()
174 {
175     scanf("%d",&n);rbt.init();//初始化
176     for(int i=1;i<=n;i++){
177         int op,x;scanf("%d%d",&op,&x);
178         if(op==1) rbt.insert(x);
179         else if(op==2) rbt.remove(x);
180         else if(op==3) printf("%dn",rbt.rnk(x));
181         else if(op==4) printf("%dn",rbt.kth(x));
182         else if(op==5) printf("%dn",rbt.pre(x));
183         else printf("%dn",rbt.nxt(x));
184     }
185     return 0;
186 }

注释版红黑树

 

原文链接: https://www.cnblogs.com/hz-Rockstar/p/11643946.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    C++STL手写版

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/303851

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月16日 上午1:05
下一篇 2023年2月16日 上午1:10

相关推荐