红黑树 C++实现

#ifndef __RED_BLACK_TREE_H__
#define __RED_BLACK_TREE_H__

namespace lxf {
    template <typename Key, typename Value>
    class RedBlackTree {
        struct Node {
            enum Color { RED, BLACK };
            Key key;
            Value value;
            Node *left;
            Node *right;
            Node *parent;
            Color color;
            Node(Key pkey, Value pvalue, Color pcolor) : key(pkey), value(pvalue), left(nullptr), right(nullptr), parent(nullptr), color(pcolor) {}
        };
        Node *root;
        void rotateLeft(Node *x);
        void rotateRight(Node *x);

        Node* deleteMin(Node* head);
        Node* min(Node *head);
    public:
        void insert(Key key, Value value);
        void erase(Key key);
        RedBlackTree():root(nullptr) {}
    };

    /*
    * 对红黑树的节点(x)进行左旋转
    *
    * 左旋示意图(对节点x进行左旋):
    *      px                              px
    *     /                               /
    *    x                               y
    *   /  \      --(左旋)-->           / \                #
    *  lx   y                          x  ry
    *     /   \                       /  \
    *    ly   ry                     lx  ly
    *
    *
    */
    template<typename Key, typename Value>
    inline void RedBlackTree<Key, Value>::rotateLeft(Node * x)
    {
        Node *y = x->right;

        x->right = y->left;
        if (y->left != nullptr)
            y->left->parent = x;

        y->parent = x->parent;
        if (x->parent == nullptr)
            root = y;
        else {
            if (x->parent->left == x)
                x->parent->left = y;
            else
                x->parent->right = y;
        }
        y->left = x;
        x->parent = y;
    }

    /*
    * 对红黑树的节点(y)进行右旋转
    *
    * 右旋示意图(对节点y进行左旋):
    *            py                               py
    *           /                                /
    *          y                                x
    *         /  \      --(右旋)-->            /  \                     #
    *        x   ry                           lx   y
    *       / \                                   / \                   #
    *      lx  rx                                rx  ry
    *
    */
    template<typename Key, typename Value>
    inline void RedBlackTree<Key, Value>::rotateRight(Node * x)
    {
        Node *x = y->left;
        y->left = x->right;
        if (x->right != nullptr)
            x->right->parent = y;
        x->parent = y->parent;
        if (y->parent == nullptr)
            root = x;
        else {
            if (y == y->parent->right)
                y->parent->right = x;
            else
                y->parent->left = x;
        }
        x->right = y;
        y->parent = x;
    }

    template<typename Key, typename Value>
    inline typename RedBlackTree<Key, Value>::Node * RedBlackTree<Key, Value>::deleteMin(Node * head)
    {
        if (head == nullptr)
            return nullptr;
        Node *node = head;
        Node *lastNode = nullptr;
        while (node->left != nullptr)
        {
            lastNode = node;
            node = node->left;
        }
        lastNode->left = node->right;
        if (node->right != nullptr)
            node->right->parent = lastNode;
        return head;
    }

    template<typename Key, typename Value>
    inline typename RedBlackTree<Key, Value>::Node * RedBlackTree<Key, Value>::min(Node * head)
    {
        if (head == nullptr)
            return nullptr;
        Node *node = head;
        while (node->left != nullptr)
            node = node->left;
        return node;
    }

    template<typename Key, typename Value>
    inline void RedBlackTree<Key, Value>::insert(Key key, Value value)
    {
        Node *parent = nullptr;
        Node **ppNode = &root;
        while (*ppNode != nullptr)
        {
            parent = *ppNode;
            if (key < (*ppNode)->key)
                ppNode = &((*ppNode)->left);
            else
                ppNode = &((*ppNode)->right);
        }
        if (*ppNode == nullptr) {
            *ppNode = new Node(key, value, RED);
            (*ppNode)->parent = parent;
        }
            
        // 结点是根
        if (parent == nullptr) {
            root->color = Node::BLACK;
            return;
        }
        
        Node *node = *ppNode;
        // 调整
        while (node->parent->color == Node::RED)
        {
            Node *parent = node->parent;
            Node *gparent = node->parent->parent;
            if (parent == gparent->left)
            {
                Node *uncle = gparent->right;
                if (uncle->color == RED)
                {
                    parent->color = BLACK;
                    uncle->color = BLACK;
                    gparent->color = RED;
                    node = gparent;
                }
                else if (uncle->color == BLACK)
                {
                    if (node == parent->right)
                    {
                        node = parent;
                        rotateLeft(node);
                    }
                    else
                    {
                        parent->color = BLACK;
                        gparent->color = RED;
                        rotateRight(gparent);
                    }
                }
            }
            else if (parent == gparent->right)
            {
                Node *uncle = gparent->left;
                if (uncle->color == RED)
                {
                    parent->color = BLACK;
                    uncle->color = BLACK;
                    gparent->color = RED;
                    node = gparent;
                }
                else if (uncle->color == BLACK)
                {
                    if (node == parent->left)
                    {
                        node = parent;
                        rotateRight(node);
                    }
                    else
                    {
                        parent->color = BLACK;
                        gparent->color = RED;
                        rotateLeft(gparent);
                    }
                }
            }
        }
    }

    template<typename Key, typename Value>
    inline void RedBlackTree<Key, Value>::erase(Key key)
    {
        Node *lastNode = nullptr;
        Node *node = root;
        while (node != nullptr)
        {
            if (key < node->key) {
                lastNode = node;
                node = node->left;
            }
            else if (key > node->key) {
                lastNode = node;
                node = node->right;
            }
            else {
                Node **plastNode = nullptr;
                // 注意树根
                if (lastNode == nullptr)
                    plastNode = &root;
                else
                    plastNode = &lastNode;
                // 无节点的情况
                if (node->left == nullptr && node->right == nullptr)
                {
                    if ((*plastNode)->left == node)
                    {
                        (*plastNode)->left = nullptr;
                        delete node;
                    }
                    else if ((*plastNode)->right == node)
                    {
                        (*plastNode)->right = nullptr;
                        delete node;
                    }
                }
                // 两个节点的情况
                else if (node->left != nullptr && node->right != nullptr) {
                    Node *star = min(node->right);
                    star->right = deleteMin(node->right);
                    if (star->right != nullptr)
                        star->right->parent = star;
                    star->left = node->left;
                    if (star->left != nullptr)
                        star->left->parent = star;
                    delete node;
                }
                // 只有一个节点的情况
                else if (node->left == nullptr) {
                    if ((*plastNode)->left == node) {
                        (*plastNode)->left = node->right;
                        if (node->right != nullptr)
                            node->right->parent = *plastNode;
                        delete node;
                    }
                    else if ((*plastNode)->right == node) {
                        (*plastNode)->right = node->right;
                        if (node->right != nullptr)
                            node->right->parent = *plastNode;
                        delete node;
                    }
                }
                else if (node->right == nullptr) {
                    if ((*plastNode)->right == node) {
                        (*plastNode)->right = node->left;
                        if (node->left != nullptr)
                            node->left->parent = *plastNode;
                        delete node;
                    }
                    else if ((*plastNode)->left == node) {
                        (*plastNode)->left = node->left;
                        if (node->left != nullptr)
                            node->left->parent = *plastNode;
                        delete node;
                    }
                }
                            
            }
        }

        while (node != root && node->color == BLACK)
        {
            if (node == node->parent->left)
            {
                Node* brother = node->parent->right;
                if (brother->color == RED)
                {
                    brother->color = BLACK;
                    node->parent->color = RED;
                    rotateLeft(node->parent);
                }
                else
                {
                    if (brother->left->color == BLACK && brother->right->color == BLACK)
                    {
                        brother->color = RED;
                        node = node->parent;
                    }
                    else if (brother->right->color == BLACK)
                    {
                        brother->color = RED;
                        brother->left->color = BLACK;
                        RotateRight(brother);
                    }
                    else if (brother->right->color == RED)
                    {
                        brother->color = node->parent->color;
                        node->parent->color = BLACK;
                        brother->right->color = BLACK;
                        rotateLeft(node->parent);
                        node = root;
                    }
                }
            }
            else
            {
                Node* brother = node->parent->left;
                if (brother->color == RED)
                {
                    brother->color = BLACK;
                    node->parent->color = RED;
                    rotateRight(node->parent);
                }
                else
                {
                    if (brother->left->color == BLACK && brother->right->color == BLACK)
                    {
                        brother->color = RED;
                        node = node->parent;
                    }
                    else if (brother->left->color == BLACK)
                    {
                        brother->color = RED;
                        brother->right->color = BLACK;
                        rotateLeft(brother);
                    }
                    else if (brother->left->color == RED)
                    {
                        brother->color = node->parent->color;
                        node->parent->color = BLACK;
                        brother->left->color = BLACK;
                        rotateRight(node->parent);
                        node = root;
                    }
                }
            }
        }
        node->parent = root;   //最后将node置为根结点,  
        node->color = BLACK;    //并改为黑色。
    }    
}

#endif /*__RED_BLACK_TREE_H__*/

 

posted @ 2015-12-02 18:23  sdlwlxf  阅读(185)  评论(0编辑  收藏  举报