红黑树(算法导论第三版)

34 篇文章 0 订阅
13 篇文章 0 订阅
#ifndef REDBLACKTREE_REDBLACKTREE_H
#define REDBLACKTREE_REDBLACKTREE_H

template<typename T>
class RedBlackTree
{
    enum Color{
        RED,BLACK
    };
    class Node{
    public:
        T key;
        Color color;
        Node* left;
        Node* right;
        Node* parent;
        Node():key{},color(BLACK),left(nullptr),right(nullptr){}
        Node(T key):key(key),color(BLACK),left(nullptr),right(nullptr){}
    };
    Node* NIL;
    Node *root;
public:
    RedBlackTree()
    {
        NIL = new Node();
        root = NIL;
    }
    ~RedBlackTree()
    {
        postorder_walk_delete(root);
        if(NIL)
        {
            delete NIL;
            NIL = nullptr;
        }
    }
    void insert(T key)
    {
        Node* node = new Node();
        node->key = key;
        RB_insert(node);
    }
    bool remvoe(T key)
    {
        Node* node = search(key);
        if(node == NIL)
            return false;
        RB_delete(node);
        delete node;
        node = nullptr;
        return true;
    }
    void show(void(*f)(T))
    {
        if(root == NIL)
            return;
        inorder_walk(root,f);
    }
private:
    //    x
    //      \
    //       y
    void left_rotate(Node *x)
    {
        Node *y = x->right;
        x->right = y->left;
        if(y->left != NIL)
            y->left->parent = x;
        y->parent = x->parent;
        if(x->parent == NIL)
            root = y;
        else if(x == x->parent->left)
            x->parent->left = y;
        else
            x->parent->right = y;
        y->left = x;
        x->parent = y;
    }
    //          y        ->       x
    //       /   \       ->    /    \
    //      x     c      ->   a      y
    //    /   \          ->        /   \
    //  a      b         ->       b     c
    void right_rotate(Node *y)
    {
        Node* x = y->left;
        y->left = x->right;
        if(x->right != NIL)
            x->right->parent = y;
        x->parent = y->parent;
        if(y->parent == NIL)
            root = x;
        else if(y == y->parent->left)
            y->parent->left = x;
        else
            y->parent->right = x;
        x->right = y;
        y->parent = x;
    }
    void RB_insert(Node *z)
    {
        Node* y = NIL;
        Node* x = root;
        while (x!= NIL)
        {
            y = x;
            if(z->key<x->key)
                x = x->left;
            else
                x = x->right;
        }
        z->parent = y;
        if(y == NIL)
            root = z;
        else if(z->key<y->key)
            y->left = z;
        else
            y->right = z;
        z->left = NIL;
        z->right = NIL;
        z->color = RED;
        RB_insert_fixup(z);
    }
    void RB_insert_fixup(Node* z)
    {
        Node *y = nullptr;
        while (z->parent->color == RED)
        {
            if(z->parent == z->parent->parent->left)
            {
                y = z->parent->parent->right;
                if(y->color == RED)
                {
                    z->parent->color = BLACK;
                    y->color = BLACK;
                    z->parent->parent->color = RED;
                    z = z->parent->parent;
                }
                else {
                    if (z == z->parent->right) {
                        z = z->parent;
                        left_rotate(z);
                    }
                    z->parent->color = BLACK;
                    z->parent->parent->color = RED;
                    right_rotate(z->parent->parent);
                }
            }
            else
            {
                y = z->parent->parent->left;
                if(y->color == RED)
                {
                    z->parent->color = BLACK;
                    y->color = BLACK;
                    z->parent->parent->color = RED;
                    z = z->parent->parent;
                }
                else
                {
                    if(z == z->parent->left)
                    {
                        z = z->parent;
                        right_rotate(z);
                    }
                    z->parent->color = BLACK;
                    z->parent->parent->color = RED;
                    left_rotate(z->parent->parent);
                }
            }
        }
        root->color = BLACK;
    }
    void RB_transplant(Node *u,Node*v)
    {
        if(u->parent == NIL)
            root = v;
        else if(u == u->parent->left)
            u->parent->left = v;
        else
            u->parent->right = v;
        v->parent = u->parent;
    }
    void RB_delete(Node* z)
    {
        Node* y = z;
        Node* x = NIL;
        Color y_original_color = y->color;
        if(z->left == NIL)
        {
            x = z->right;
            RB_transplant(z,z->right);
        }
        else if(z->right == NIL)
        {
            x = z->left;
            RB_transplant(z,z->left);
        }
        else
        {
            y = minimum(z->right);
            y_original_color = y->color;
            x = y->right;
            if(y->parent == z)
            {
                x->parent = y;
            }
            else
            {
                RB_transplant(y,y->right);
                y->right = z->right;
                y->right->parent = y;
            }
            RB_transplant(z,y);
            y->left = z->left;
            y->left->parent = y;
            y->color = z->color;
        }
        if(y_original_color == BLACK)
        {
            PB_delete_fixup(x);
        }
    }
    void PB_delete_fixup(Node* x)
    {
        while (x != root && x->color == BLACK)
        {
            if(x == x->parent->left)
            {
                Node* w = x->parent->right;
                if(w->color == RED)
                {
                    w->color = BLACK;
                    x->parent->color = RED;
                    left_rotate(x->parent);
                    w = x->parent->right;
                }
                if(w->left->color == BLACK && w->right->color == BLACK)
                {
                    w->color = RED;
                    x = x->parent;
                }
                else
                {
                    if(w->right->color == BLACK)
                    {
                        w->left->color = BLACK;
                        w->color = RED;
                        right_rotate(w);
                        w = x->parent->right;
                    }
                    w->color = x->parent->color;
                    x->parent->color = BLACK;
                    w->right->color = BLACK;
                    left_rotate(x->parent);
                    x = root;
                }
            }
            else
            {
                Node* w = x->parent->left;
                if(w->color == RED)
                {
                    w->color = BLACK;
                    x->parent->color = RED;
                    right_rotate(x->parent);
                    w = x->parent->left;
                }
                if(w->left->color == BLACK && w->right->color == BLACK)
                {
                    w->color = RED;
                    x = x->parent;
                }
                else
                {
                    if(w->left->color == BLACK)
                    {
                        w->right->color = BLACK;
                        left_rotate(w);
                        w = x->parent->left;
                    }
                    w->color = x->parent->color;
                    x->parent->color = BLACK;
                    w->left->color = BLACK;
                    right_rotate(x->parent);
                    x = root;
                }
            }
        }
        x->color = BLACK;
    }
    Node* minimum(Node * x)
    {
        while (x->left != NIL)
        {
            x = x->left;
        }
        return x;
    }
    Node* maximum(Node* x)
    {
        while (x->right != NIL)
        {
            x = x->right;
        }
        return x;
    }
    Node* search(T key)
    {
        Node* x = root;
        while (x != NIL && key != x->key)
        {
            if(key<x->key)
                x = x->left;
            else
                x = x->right;
        }
        return x;
    }
    void inorder_walk(Node* x,void(*f)(T))
    {
        if(x != NIL)
        {
            inorder_walk(x->left,f);
            f(x->key);
            inorder_walk(x->right,f);
        }
    }
    void postorder_walk_delete(Node* x)
    {
        if(x!=NIL)
        {
            postorder_walk_delete(x->left);
            postorder_walk_delete(x->right);
            delete x;
        }
    }
};


#endif //REDBLACKTREE_REDBLACKTREE_H
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值