红黑树

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

红黑树:根必为黑,红节点不会连续,黑高相等
保证了查询复杂度小于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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值