RBTree(红黑树)

                                                                                 红黑树
红黑树(Red Black Tree)和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡。
红黑树是一颗二叉搜索树,它的每一个节点增加了一个存储位用来表示颜色,可以是Red也可以是Black,通过对任意一条根到叶子节点的颜色来约束,红黑树保证最长路径是最短路径的两倍,因此近似平衡;
红黑树的性质:
1:每个节点不是红色就是黑色
2:根节点是黑色
3:如果一个节点时红,则它两个子节点是黑色的(没有连续的红色)
4:对每个节点,从该节点到其后代的所有叶子节点的简单路径,均有相同数目的黑节点(每条路径的黑色节点色数目相同)
两者的差别:AVL树是完全平衡树,更接近满二叉树,因此它的时间复杂度是O(lgN),在二叉树插入删除时旋转多,维护起来比较麻烦,但相比更直观。而RBT树是近似平衡树,时间复杂度是2O(log n),旋转较少,相对维护起来比较简单,但是相比更抽象。相对来说运用最多的还是RBTree。
红黑树的应用: 在C++ STL中,很多部分都运用了红黑树包括:Linux内核,java  c#  还有(包括set, multiset, map, multimap)应用了红黑树的变体(SGI STL中的红黑树有一些变化,这些修改提供了更好的性能,以及对set操作的支持)等等。
下面就是节点的颜色转换以及旋转的情况:



在此只展示了parent为孩子的情况,parent为右孩子情况类似。
具体实现源码如下:
#include <math.h>
#include <iostream>
using namespace std;
enum colour
{
     BLACK,
     RED,
};
template<class K, class V>
struct RBTreeNode
{
    K _key;
    V _val;
    colour _col;
    RBTreeNode<K, V>* _left;
    RBTreeNode<K, V>*  _right;
    RBTreeNode<K, V>*  _parent;
    int _bf;
    RBTreeNode(const K& key, const V& value)
         :_left(NULL)
         , _right(NULL)
         , _parent(NULL)
         , _key(key)
         , _val(value)
         , _bf(0)
         , _col(RED)
    {}
};
template<class K, class V>
class RBTree
{
    typedef RBTreeNode<K, V>   Node;
public:
    RBTree()
         :_root(NULL)
    {}
    ~RBTree()
    {}
    bool Insert(const K& key, const V& value)
    {
         if (_root == NULL)
         {
             _root = new Node(key, value);
             _root->_col = BLACK;
             return true;
         }
         Node* parent = NULL;
         Node* cur = _root;
         while (cur)
         {
             if (cur->_key < key)//右边 
             {
                 parent = cur;
                 cur = cur->_right;
             }
             else if (cur->_key>key)//左边 
             {
                 parent = cur;
                 cur = cur->_left;
             }
             else
             {
                 return false;//不存在 
             }
         }
         cur = new Node(key, value);
         if (key > parent->_key)
         {
             parent->_right = cur;
             cur->_parent = parent;
         }
         else
         {
             parent->_left = cur;
             cur->_parent = parent;
         }
         while (parent && parent->_col==RED)
         {
             Node* grandparent = parent->_parent;
             if (grandparent->_left==parent)  //父亲在左边
             {
                 Node* uncle = grandparent->_right;
                 if (uncle&&uncle->_col==RED)
                 {
                      parent->_col = BLACK;
                      uncle->_col = BLACK;
                      grandparent->_col = RED;
                      cur = grandparent;         //向上调整
                      parent = cur->_parent;       //
                 }
                 else   //叔叔不存在或者叔叔为黑,需要旋转
                 {
                if (cur==parent->_right)
                    {
                      RotateL(parent);
                      swap(parent,cur);
                    }
                      RotateR(grandparent);
                      parent->_col = BLACK;
                      grandparent->_col = RED;
                      break;
                 }
             }
             else    //parent = grandparent->_right;
             {
                 Node* uncle = grandparent->_left;
                 if (uncle&&uncle->_col == RED)
                 {
                      parent->_col = BLACK;
                      uncle->_col = BLACK;
                      grandparent->_col = RED;
                      cur = grandparent;         //向上调整
                      parent = cur->_parent;         //
                 }
                 else   //叔叔不存在或者叔叔为黑,需要旋转
                 {
                      if (cur == parent->_left)    
                      {
                          RotateR(parent);
                          swap(parent, cur);   // 若cur在parent的左,cur->_key < parent->_key,旋转后必须交换才符合_key值得排布规则。
                      }
                      RotateL(grandparent);
                      parent->_col = BLACK;
                      grandparent->_col = RED;
                 }
             }
         }
     _root->_col = BLACK;
         return true;
    }
    bool  Isbalance()
    {
         if (_root==NULL)
         {
             return true;
         }
         if (_root->_col==RED)
         {
             return false;
         }
         int Blacknum = 0;
         Node* left = _root;
         while (left)     //遍历任意一边,计算出黑色节点的个数,作为一个基准,将此数与其他路上的书做较,只要不相等就可以说明此树不是平衡红黑树
         {
             if (left->_col==BLACK)
             {
                 Blacknum++;
             }
             left = left->_left; 
         }
         int num = 0;
         return _IsBalance(_root, Blacknum, num);
    }
    bool _IsBalance(Node* root, const int Blacknum, int num)
    {
         if (root == NULL)
         {
             if (num != Blacknum)
             {
             cout << "黑节点个数不等" << endl;
                 return false;
             }
             else
             {
                 return true;
             }
         }
         if (root->_col == BLACK)
         {
             num++;
         }
         if ((root->_col == RED) && (root->_parent->_col == RED))
         {
             cout << root->_key << "  " << root->_parent->_key << "  " << endl;
             return false;
         }
         return _IsBalance(root->_left, Blacknum, num) && _IsBalance(root->_right, Blacknum, num);
    }
    void RotateL(Node* parent)// 左单旋
    {
         Node* subR = parent->_right;
         Node* subRL = subR->_left;
         parent->_right = subRL;
         if (subRL)     //开始旋转    
         {
             subRL->_parent = parent;
         }   //
         subR->_left = parent;
         subR->_parent = parent->_parent;
         Node* ppnode = parent->_parent;
         parent->_parent = subR;/
         if (ppnode == NULL)
         {
             _root = subR;
             subR->_parent = NULL;
         }
         else if (parent == ppnode->_left)
         {
             ppnode->_left = subR;
         }
         else
         {
             ppnode->_right = subR;
         }
         subR->_parent = ppnode;
    }
    void RotateR(Node* parent)
    {
    Node* subL = parent->_left;
    Node* subLR = subL->_right;
    parent->_left = subLR;
    if (subLR)
    {
    subLR->_parent = parent;
    }
    subL->_right = parent;
    subL->_parent = parent->_parent;
    Node* ppnode = parent->_parent;
    parent->_parent = subL;
    if (ppnode == NULL)
    {
    _root = subL;
    subL->_parent = NULL;
    }
    else if (ppnode->_left == parent)
    {
    ppnode->_left = subL;
    }
    else
    {
    ppnode->_right = subL;
    }
    subL->_parent = ppnode;
    }
    void InOrder()
    {
         _InOrder(_root);
         cout << endl;
    }
protected:
    void _InOrder(Node* root)
    {
         if (root == NULL)
         {
             return;
         }
         _InOrder(root->_left);
         cout << root->_key << " ";
         _InOrder(root->_right);
    }
private:
    Node* _root;
};
void Test()
{
    int a[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 };
    //int a[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14 };
    //int a[] = {2,3,1,4,5};
    //int a[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 };
    RBTree<int, int> t;
    for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); i++)
    {
         //t.Insert(a[i], i);
         t.Insert(a[i],i);
    cout << t.Isbalance()<< endl;
    }
    t.InOrder();
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值