• 红黑树


    最近要准备阿里的面试
    就学习下红黑树

    红黑树:根必为黑,红节点不会连续,黑高相等
    保证了查询复杂度小于logn

    当然比较难理解的是插入,删除
    怎么就旋转跳跃,就又变成平衡了呢
    真是牛逼

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 1e5+5;
    
    struct RedBlack {
        int color, key, left, right, parent; // 0 black 1 red
    }E[N]; 
    int tot;
    int root;
    
    void left_rotate(int x) {
        int y = E[x].right;
        E[x].right = E[y].left;
        if(E[y].left) {
            E[E[y].left].parent = x;
        }
        E[y].parent = E[x].parent;
        if(E[x].parent == 0) root = y;
        else if( x == E[E[x].parent].left ) E[E[x].parent].left = y;
        else E[E[x].parent].right = y;
        E[y].left = x;
        E[x].parent = y;
    }
    void right_rotate(int x) {
        int y = E[x].left;
        E[x].left = E[y].right;
        if(E[y].right) {
            E[E[y].right].parent = x;
        }
        E[y].parent = E[x].parent;
        if(E[x].parent == 0) root = y;
        else if( x == E[E[x].parent].left ) E[E[x].parent].left = y;
        else E[E[x].parent].right = y;
        E[y].right = x;
        E[x].parent = y;
    }
    void FixInsert(int z) {
        int y;
        while(E[E[z].parent].color == 1) {
            if(E[z].parent == E[E[E[z].parent].parent].left) {
                y = E[E[E[z].parent].parent].right;
                if(E[y].color == 1) {
                    E[E[z].parent].color = 0;
                    E[y].color = 0;
                    E[E[E[z].parent].parent].color = 1;
                    z = E[E[z].parent].parent;
                }else {
                    if(z == E[E[z].parent].right) {
                        z = E[z].parent;
                        left_rotate(z);
                    }
                    E[E[z].parent].color = 0;
                    E[E[E[z].parent].parent].color = 1;
                    right_rotate(E[E[z].parent].parent);
                }
            }else {
                y = E[E[E[z].parent].parent].left;
                if(E[y].color == 1) {
                    E[E[z].parent].color = 0;
                    E[y].color = 0;
                    E[E[E[z].parent].parent].color = 1;
                    z = E[E[z].parent].parent;
                }else {
                    if(z == E[E[z].parent].left) {
                        z = E[z].parent;
                        right_rotate(z);
                    }
                    E[E[z].parent].color = 0;
                    E[E[E[z].parent].parent].color = 1;
                    left_rotate(E[E[z].parent].parent);
                }
            }
        }
        E[root].color = 0;
    }
    void Insert(int z) {
        int x = root;
        int y = 0;
        while(x) {
            y = x;
            if(E[z].key < E[x].key) {
                x = E[x].left;
            }else x = E[x].right;
        }
        E[z].parent = y;
        if(!y) root = z;
        else if(E[z].key < E[y].key)
            E[y].left = z;
        else E[y].right = z;
    
        E[z].left = 0;
        E[z].right = 0;
        E[z].color = 1;
        FixInsert(z);
    }
    void Transplant(int u, int v) { // tanform v to u;
        if(!E[u].parent) {
            root = v;
        }else if(u == E[E[u].parent].left) {
            E[E[u].parent].left = v;
        }else E[E[u].parent].right = v;
        E[v].parent = E[u].parent;
    } 
    int treeminimum(int x) {
        while(!E[x].left) {
            x = E[x].left;
        }
        return x;
    }
    int treemaxmum(int x) {
        while(!E[x].right) {
            x = E[x].right;
        }
        return x;
    }
    void Deletefix(int x) { // 被删掉的肯定是黑色
        int w;
        while(x != root && E[x].color == 0) {
            if(x == E[E[x].parent].left) {
                w = E[E[x].parent].right;
                if(E[w].color == 1) {  // w如果是红色节点 先转化成为黑色
                    E[w].color = 0;
                    E[E[x].parent].color = 1;
                    left_rotate(E[x].parent);
                    w = E[E[x].parent].right;
                }
                if(E[E[w].left].color == 0 && E[E[w].right].color == 0) {
                    E[w].color = 1;
                    x = E[x].parent;
                }
                else {
                    if(E[E[w].right].color == 0) {
                        E[E[w].left].color = 0;
                        E[w].color = 1;
                        right_rotate(w);
                        w = E[E[x].parent].right;
                    }
                    E[w].color = E[E[x].parent].color;
                    E[E[x].parent].color = 0;
                    E[E[w].right].color = 0;
                    left_rotate(E[x].parent);
                    x = root;
                }
            }else {
                w = E[E[x].parent].left;
                if(E[w].color == 1) {
                    E[w].color = 0;
                    E[E[x].parent].color = 1;
                    right_rotate(E[x].parent);
                    w = E[E[x].parent].left;
                }
                if(E[E[w].right].color == 0 && E[E[w].left].color == 0) {
                    E[w].color = 1;
                    x = E[x].parent;
                }
                else {
                    if(E[E[w].left].color == 0) {
                        E[E[w].right].color = 0;
                        E[w].color = 1;
                        left_rotate(w);
                        w = E[E[x].parent].left;
                    }
                    E[w].color = E[E[x].parent].color;
                    E[E[x].parent].color = 0;
                    E[E[w].left].color = 0;
                    right_rotate(E[x].parent);
                    x = root;
                }                                      
            }
        }
        E[x].color = 0; 
    }
    void Delete(int z) {
        int y = z; int x;       
        int yorgcol = E[y].color;
        if(!E[z].left) {
            x = E[z].right;
            Transplant(z, E[z].right);
        }else if(!E[z].right) {
            x = E[x].left;
            Transplant(z, E[z].left);
        }else {
            y = treeminimum(E[z].right);
            yorgcol = E[y].color;
            x = E[y].right;
            if(E[y].parent == z) {
                E[x].parent = y;
            }else {
                Transplant(y, E[y].right);
                E[y].right = E[z].right;
                E[E[y].right].parent = y;
            }
            Transplant(z, y);
            E[y].left = E[z].left;
            E[E[y].left].parent = y;
            E[y].color = E[z].color;
        }
        if(yorgcol == 0) {
            Deletefix(x);
        }
    }
    
    int main() {
        int n;
        while(~scanf("%d",&n)) {
            root = 0; tot = 0;
            for(int i = 1; i <= n; ++i) {
                int ty; scanf("%d",&ty);
                if(ty == 1) {
                    int a; scanf("%d",&a);
                    E[++tot].key = a;
                    Insert(tot);
                }else {
                    Delete(tot);
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    php自定义函数call_user_func和call_user_func_array详解
    微信开发(一) 服务器配置
    6487. 【GDOI2020模拟02.29】列强争霸war
    关于循环顺序对时间影响的一点研究
    6486. 【GDOI2020模拟02.25】向日葵人生
    6485. 【GDOI2020模拟02.25】沙塔斯月光
    6478. 【GDOI2020模拟02.19】C(上下界费用流、费用流消负环)
    6461. 【GDOI2020模拟02.05】生成树(矩阵树及其扩展、二维拉格朗日插值)
    上下界网络流&费用流
    6467. 【GDOI2020模拟02.09】西行寺无余涅槃(FWT的性质)
  • 原文地址:https://www.cnblogs.com/Basasuya/p/8433715.html
Copyright © 2020-2023  润新知