红黑树的简单实现-RBTree

红黑树是一个被广泛运用的平衡二叉树,同时满足以下规则
1.每个节点不是红色就是黑色
2.根节点为黑
3.不存在连续红节点
4.每条路径上黑色节点数相等,(空节点视为黑色)
这样一来,红黑树可以保持最长路径不超过最短路径的两倍,保持近似平衡,搜索时间复杂度是O(lgN)

下面是红黑树调节节点平衡与颜色的简介,当插入节点后出现连续红节点后,判断叔叔是否存在和叔叔的颜色,
若是叔叔存在且颜色为红时
这里写图片描述
叔叔不存在 或者 叔叔存在且颜色为黑时,如下图调整,四种情况四种旋转
这里写图片描述
下面是实现代码:

#include <iostream>
using namespace std;


enum Color
{
    RED,
    BLACK
};
template <class T>
struct RBTreeNode
{
    RBTreeNode<T>* _left;
    RBTreeNode<T>* _right;
    RBTreeNode<T>* _parent;
    Color _color;
    T _key;

    RBTreeNode(T key)
        :_left(NULL),
        _right(NULL),
        _parent(NULL),
        _color(RED),
        _key(key)
    {}
};

template <class T>
class RBTree
{
    typedef RBTreeNode<T> Node;
public:
    RBTree()
        :_root(NULL)
    {}
    void RotateR(Node* parent)
    {
        Node* subL = parent->_left;
        Node* PParent = parent->_parent;
        Node* subLR = subL->_right;

        parent->_left = subLR;
        subL->_right = parent;
        parent->_parent = subL;
        if (subLR)
        {
            subLR->_parent = parent;
        }
        if (PParent==NULL)
        {
            _root = subL;
            subL->_parent = NULL;
        }
        else if (PParent->_key > parent->_key)
        {
            subL->_parent = PParent;
            PParent->_left = subL;
        }
        else if (PParent->_key < parent->_key)
        {
            subL->_parent = PParent;
            PParent->_right = subL;
        }

    }
    void RotateL(Node* parent)
    {
        Node* PParent = parent->_parent;
        Node* subR = parent->_right;
        Node* subRL = subR->_left;

        parent->_right = subRL;
        subR->_left = parent;
        parent->_parent = subR;
        if (subRL)
        {
            subRL->_parent = parent;
        }
        if (PParent == NULL)
        {
            _root = subR;
            subR->_parent = NULL;
        }
        else if (PParent->_key > parent->_key)
        {
            subR->_parent = PParent;
            PParent->_left = subR;
        }
        else if (PParent->_key < parent->_key)
        {
            subR->_parent = PParent;
            PParent->_right = subR;
        }

    }
    bool Insert(const T& key)
    {
        if (_root == NULL)//空树直接插入
        {
            _root = new Node(key);
            _root->_color = BLACK;
            return true;
        }
        Node* cur = _root;//非空 从根节点开始 向下找位置
        Node* parent = NULL;
        while (cur)
        {
            if (key == cur->_key)
            {
                return false;
            }
            else if (key < cur->_key)
            {
                parent = cur;
                cur = cur->_left;
            }
            else if (key>cur->_key)
            {
                parent = cur;
                cur = cur->_right;
            }
        }

        cur = new Node(key);
        cur->_parent = parent;

        if (parent->_key > key)
        {
            parent->_left = cur;
        }
        else if (parent->_key < key)
        {
            parent->_right = cur;
        }

        //调节节点颜色
        while (parent&&parent->_color == RED)
        {
            Node* PParent = parent->_parent;
            if (PParent->_left == parent)//父亲是祖父的左
            {
                Node* uncle = PParent->_right;
                if (uncle&&uncle->_color == RED)//叔叔为红
                {
                    parent->_color = uncle->_color = BLACK;
                    PParent->_color = RED;
                    cur = PParent;
                    parent = cur->_parent;
                }
                else//叔叔不存在  或者叔叔为黑
                {
                    if (cur == parent->_left)
                    {
                        //右单旋
                        RotateR(PParent);
                        PParent->_color = RED;//祖父变红
                        parent->_color = BLACK;//父亲变黑
                    }
                    else//左右双旋
                    {
                        RotateL(parent);
                        RotateR(PParent);
                        PParent->_color = RED;//祖父 变红
                        cur->_color = BLACK;//当前节点变黑
                    }
                }
            }
            else if (PParent->_right == parent)//父亲是祖父的右
            {
                Node* uncle = PParent->_left;
                if (uncle&&uncle->_color == RED)//叔叔为红
                {
                    parent->_color = uncle->_color = BLACK;
                    PParent->_color = RED;
                    cur = PParent;
                    parent = cur->_parent;
                }
                else//叔叔不存在  或者叔叔为黑
                {
                    if (cur == parent->_right)//cur为父亲的右 左单旋
                    {
                        RotateL(PParent);//左单旋
                        parent->_color = BLACK;//父亲变红
                        PParent->_color = RED;//祖父变黑
                    }
                    else
                    {
                        //右左双旋
                        RotateR(parent);
                        RotateL(PParent);
                        cur->_color = BLACK;
                        PParent->_color = RED;
                    }
                }
            }_root->_color = BLACK;

        }return true;

    }

    void Printf()
    {
        _printf(_root);
    }
    void _printf(Node*& root)
    {
        if (root == NULL)
            return;
        _printf(root->_left);
        printf("%d  ",root->_key);
        _printf(root->_right);
    }
protected:
    Node* _root;
};


int main()
{
    int a[] = {3,2,4,5,7,9,8,0,12,13,15};
    /*int a[] = { 10,5,3 };*/
    /*int a[] = { 10,5,8 };*/
    /*int a[] = { 3,5,10 };*/
    /*int a[] = { 3,10,5};*/
    RBTree<int> t;
    for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
        t.Insert(a[i]);
    t.Printf();
    system("pause");
    return 0;
}

结果如下
这里写图片描述
如有不足 ,请不吝赐教

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值