【数据结构】实现红黑树!!!

红黑树详解
本文介绍了红黑树的基本概念,包括创建原则、颜色属性及其约束条件。详细解释了五种插入结点的情况及其处理方法,并提供了红黑树创建的代码实现。

相对于AVL树来说,红黑树去掉了AVL树里面的平衡因子,利用树节点的颜色来调整数的平衡。
红黑树的创建原则:

  1. 每个节点的颜色不是黑色就是红色
  2. 树的根节点是黑色的
  3. 如果一个节点的颜色是红色的,那么它的里两个孩子结点颜色是黑色的(即,没有两个连续的红色结点)
  4. 对于每个节点,在其后面的简单路径上面的黑色结点的个数是相同的
  5. 每个叶子节点都是黑色的(叶子节点是指空节点)

:当满足上面的颜色限制的时候,最长路径上面的结点个数最多不超过最短路径的两倍

在红黑树里面需要挂入的结点的颜色无论红黑都可以的,但是假如是黑色,那么就不满足条件4,相对来说需要调整的范围大。假如是红色,那么不满足局部,对局部结点进行调整就可以了。所以在创建结点的时候结点的颜色标记成红色。


红黑树的插入
情况1:当树是空树的时候?
这里写图片描述
解决办法:将插入的结点直接挂上面,并且将结点的颜色标记成黑色。

情况2:插入的结点的父节点是黑色的?
这里写图片描述
解决方法:直接插入结点

情况3:当g–黑色,p–红色,u–红色?
这里写图片描述
解决方法:将p、u结点颜色改为黑色,g结点的颜色改为红色,然后再以g结点为基准向上调整

情况4:当g–黑,p–红,u不存在或者u–黑?
这里写图片描述
解决方法:将p、g结点的位置交换,并且两结点改变颜色。

情况5:当g–黑,p–红,u不存在或者u–黑,并且当p为g的左孩子,cur为p的右孩子或者p为g的右孩子,cur为p的左孩子?
这里写图片描述
解决方法:将cur结点进行左单旋或者右单旋,然后再按照情况4的解决方法进行调整。

红黑树的实现(仅创建):


#ifndef _RWTREE_H
#define _RWTREE_H
#include<iostream>
using namespace std;


enum color{RED,BLACK};
template<class T>
struct RBTreeNode
{
    RBTreeNode(T d)
    :left(NULL)
    ,right(NULL)
    ,_parent(NULL)
    ,_color(RED)
    ,value(d)
    {}
    RBTreeNode<T>* left;
    RBTreeNode<T>* right;
    RBTreeNode<T>* _parent;
    color _color;
    T value;
};

template<class T>
class RWTree
{
    typedef RBTreeNode<T> Node;
    public:
    RWTree(T* arr,size_t size)
    :_root(NULL)
    {
        if(NULL == arr)
            return ;
        for(int i=0;i<size;i++)
            Insert(arr[i]);
    }
    void Insert(T d)
    {
        _Insert(_root,d);
    }

private:


    void _Insert(Node* root ,T d)
    {
        Node* cur = new Node(d);
        if(NULL == root)
            _root = cur;
        else
        {
            while(root)
            {
                if(d < root->value)
                    root = root->left;
                else
                    root = root->right;
            }       
            if(d < root->value)
                root->left = cur;
            else
                root->right = cur;
        }
        Adjust(cur);
    }

    void Adjust(Node* cur)
    {
        Node* parent = cur->_parent;
        if(parent == NULL)              //情况1
            _root = cur;
        else 
        {
            if(parent->_color == RED )
            {
                Node* grand = parent->_parent;
                Node* uncle = NULL;
                if(grand->left == parent)
                    uncle = grand->right;
                else if(grand->right == parent)
                    uncle = grand->left;
                if(uncle && uncle->_color == RED)       //情况3
                {
                    grand->_color = RED;
                    parent->_color = BLACK;
                    uncle->_color = BLACK;
                    Adjust(grand);
                }
                else
                {
                    if(cur == parent->left && parent == grand->left)     //情况4
                     {
                        parent->_color = BLACK;
                        grand->_color = RED;
                        swap_R(grand);
                    }
                    else if( cur == parent->right && parent == grand->right )
                    {
                        parent->_color = BLACK;
                        grand->_color = RED;
                        swap_L(parent);
                    }
                    else if(cur == parent->right && parent == grand->left) //情况5
                    {
                        grand->left = cur;
                        cur->_parent = grand;
                        parent = cur->left;
                        parent->_parent = cur;
                        Adjust(parent);
                    }
                    else if(cur == parent->left && parent == grand->right)
                    {
                        grand->right = cur;
                        cur->_parent = grand;
                        parent = cur->right;
                        parent->_parent = cur;
                        Adjust(grand);
                    }
                }
            }
        }
    }
    void swap_L(Node* parent)
    {
        Node* subR = parent->right;
        Node* subRL = subR->left;
        Node* pparent = parent->_parent;
        if(subRL)
            subRL->_parent = parent;
        parent->right = subRL;
        subR->left = parent;
        if(pparent == NULL)
        {
            _root = subR;
        }

        else if(pparent->left == parent)
        {
            pparent->left = subR;
        }
        else
            pparent->right = subR;
        subR->_parent = pparent;
        parent->_parent = subR;

    }

    void swap_R(Node* parent)
    {
        Node* pparent = parent->_parent;
        Node* subL = parent->left;
        Node* subLR = subL->right;
        if(subLR)
            subLR->_parent = parent;
        parent->left = subLR;
        subL->right = parent;
        parent->_parent = subL;
        if(NULL == pparent)
            _root = subL;
        else if(pparent->left == parent)
            pparent->left = subL;
        else
            pparent->right = subL;
        subL->_parent = pparent;
    }

    Node* _root;
};



#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值