RBTree-红黑树的实现

如果你学习过了AVL树,那么RBTree你也会学的很快,如果你没有,你可以看看这篇博客:
http://blog.csdn.net/fengasdfgh/article/details/52917527
AVL树是一个比较严格的平衡搜索二叉树,它搜索一个数的时间复杂度为o(lgN),然而维护它的代价却显的高昂。
相信大家都对AVL树的平衡因子感到烦躁,这就是红黑树出现的原因,它比AVL树更容易维护,理解,学习。它搜索一个数的时间复杂度近似为
o(lgN)。

下面是红黑树的基本性质:
1. 每个节点,不是红色就是黑色的
2. 根节点是黑色的
3. 如果一个节点是红色的,则它的两个子节点是黑色的
4. 对每个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点。

除了以上的性质,在有的书上或者你听别人说还有第5个性质:

  1. 每个叶子节点都是黑色的。
    请注意这里的叶子节点是指的NULL节点。这个性质可有可无,它的出现只是为了完善其他性质。

和AVL树一样,我们重点分析它的节点插入操作,至于删除和其他操作,只要学会了插入操作,其他的也能自己推导。

当新节点找到插入的位置时,如果父节点father的颜色为黑,则直接插入,为红时则需要进行操作。
大致分为三种情况:

1.uncle存在且为红
我们只需把father与uncle的颜色变为黑,grandfather的颜色变为红,然后继续向上调整(这是一个递归的过程),因为
grandfather的颜色发生改变,这可能会影响到祖父节点的颜色。
这里写图片描述

但是有特殊情况:
如果grandfather为根节点,则我们只把father和uncle变为黑色。

2.uncle不存在或为黑(统一视uncle为黑色)
father为grandfather的左节点,child为father的左节点
father为grandfather的右节点,child为father的右节点
我们只需要进行一次右/左旋转,旋转轴点为grandfather。并且再把grandfather的颜色变为红,father的颜色变为黑
这里写图片描述

3uncle不存在或颜色为黑(统一视uncle为黑色)
我们只需要把这种情况转为情况2即可,需要进行一次右/左旋转,旋转轴点为father。
这里写图片描述

在写完这些后,你可以写个判断函数看你是否调整正确:

bool ISblance()
    {
        Node *cur = _root;
        int stand = 0;
        while (cur != NULL)
        {
            if (cur->_colour == BLACK)
                stand++;
            cur = cur->_left;
        }
        return ISblance(_root, 0, stand);
    }

    bool ISblance(Node *root, int count, const int stand)
    {
        if (NULL == root)
            return true;
        if (root->_colour == BLACK)
        {
            count++;

        }
        else if (root->_father && root->_father->_colour == RED)
        {
            cout << "2个红节点" << root->_key << endl;
            return false;
        }

        if ((NULL == root->_left || NULL == root->_right)&&count != stand)
        {
            cout << "路径黑节点不相等:" << root->_key << endl;
            return false;
        }
        ISblance(root->_left, count, stand);
        ISblance(root->_right, count, stand);
        return true;

    }

代码如下(只实现了插入):

#pragma once
#include <iostream>

using namespace std;

enum
{
    RED,
    BLACK,
};

template<typename K , typename T = int>
struct RBTreeNode
{
    typedef RBTreeNode<K, T>  Node;

    RBTreeNode(const K& key, const T& value= T())
        :_key(key)
        ,_value(value)
        ,_left(NULL)
        ,_right(NULL)
        ,_father(NULL)
        ,_colour(RED)
    {

    }

    const K _key;
    T _value;
    int _colour;
    Node *_left;
    Node *_right;
    Node *_father;
};



template<class K, class T = int>
class RBTree
{
public:
    typedef RBTreeNode<K, T> Node;
    typedef RBTree<K, T>     tree;

    RBTree()
        :_root(NULL) 
    {

    };

    bool insert(const K& key, const T& value = T())
    {

        Node *p = new Node(key, value);
        if (NULL == _root)
        {

            _root = p;
            p->_colour = BLACK;
            return true;
        }

        //找到要插入的位置
        Node *cur = _root;
        Node *father = NULL;
        while (NULL != cur)
        {
            father = cur;
            if (cur->_key == key)
            {
                delete p;
                return false;
            }
            else
            {
                if (cur->_key < key)
                    cur = cur->_right;
                else cur = cur->_left;
            }
        }

        if (key > father->_key)
            father->_right = p;
        else father->_left = p;
        p->_father = father;

        adjust(p, father);
        ISblance();

    }

    void middle_play()
    {
        middle_play(_root);
    }

protected:
    void middle_play(Node *root)
    {
        if (NULL == root)
            return;
        middle_play(root->_left);
        cout << root->_key << endl;
        middle_play(root->_right);
    }
    //左旋
    void rotate_left(Node *father)
    {
        Node *grandfather = father->_father;
        Node *great_father = grandfather->_father;

        grandfather->_right = father->_left;
        if (NULL != father->_left)
            father->_left->_father = grandfather;

        father->_left = grandfather;
        grandfather->_father = father;

        if (NULL != great_father)
        {
            if (great_father->_left == grandfather)
                great_father->_left = father;
            else great_father->_right = father;
        }

        else _root = father;

            father->_father = great_father;
    }
    //右旋
    void rotate_right(Node *father)
    {
        Node *grandfather = father->_father;
        Node *great_father = grandfather->_father;

        grandfather->_left = father->_right;
        if (NULL != father->_right)
            father->_right->_father = grandfather;

        father->_right = grandfather;
        grandfather->_father = father;

        if (NULL != great_father)
        {
            if (great_father->_left == grandfather)
                great_father->_left = father;
            else great_father->_right = father;
        }
        else _root = father;

        father->_father = great_father;
    }
    //左右旋
    Node *rotate_left_right(Node *father)
    {
        father = father->_right;
        rotate_left(father);
        rotate_right(father);
    }
    //右左旋
    Node *rotate_right_left(Node *father)
    {
        father = father->_left;
        rotate_right(father);
        rotate_left(father);
    }

    void adjust(Node *child, Node *father)
    {
        if (BLACK == father->_colour)
            return;
        Node *grandfather = father->_father;


        Node *uncle = NULL;
        if (father == grandfather->_left)
            uncle = grandfather->_right;
        else uncle = grandfather->_left;

        if (NULL == uncle || uncle->_colour == BLACK)
        {
            if (father == grandfather->_left)
            {
                if (father->_right == child)
                {
                    rotate_left(child);
                    father = child;
                }

                rotate_right(father);
                father->_colour = BLACK;
                grandfather->_colour = RED;
            }
            else
            {
                if (father->_left == child)
                {
                    rotate_right(child);
                    father = child;
                }

                rotate_left(father);
                father->_colour = BLACK;
                grandfather->_colour = RED;

            }
        }
        else
        {
            father->_colour = BLACK;
            uncle->_colour = BLACK;

            if (grandfather->_father != NULL)
            {
                grandfather->_colour = RED;
                adjust(grandfather, grandfather->_father);
            }
        }


    }
    bool ISblance()
    {
        Node *cur = _root;
        int stand = 0;
        while (cur != NULL)
        {
            if (cur->_colour == BLACK)
                stand++;
            cur = cur->_left;
        }
        return ISblance(_root, 0, stand);
    }

    bool ISblance(Node *root, int count, const int stand)
    {
        if (NULL == root)
            return true;
        if (root->_colour == BLACK)
        {
            count++;

        }
        else if (root->_father && root->_father->_colour == RED)
        {
            cout << "2个红节点" << root->_key << endl;
            return false;
        }

        if ((NULL == root->_left || NULL == root->_right)&&count != stand)
        {
            cout << "路径黑节点不相等:" << root->_key << endl;
            return false;
        }
        ISblance(root->_left, count, stand);
        ISblance(root->_right, count, stand);
        return true;

    }
private:
    Node *_root;
};

这里写图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值