zoukankan      html  css  js  c++  java
  • 红黑树 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__*/
  • 相关阅读:
    5款强大的Java Web开发工具
    [Visual Studio] 重置默认设置 还原默认设置
    [Visual Studio] VS2012调试时很慢的解决方案
    SQL 语句与性能之执行顺序
    SQL 语句与性能之联合查询和联合分类查询
    使用SHFB(Sandcastle Help File Builder)建立MSDN风格的代码文档
    循序渐进地代码重构
    博客收藏
    [已解决]:调用 LoadLibraryEx 失败,在 ISAPI 筛选器 "c:WindowsMicrosoft.NETFrameworkv4.0.30319\aspnet_filter.
    [Visual Studio] .vsix项目模板制作
  • 原文地址:https://www.cnblogs.com/sdlwlxf/p/5013806.html
Copyright © 2011-2022 走看看