RBTree(红黑树)

来源:互联网 发布:华润儿童漆怎么样知乎 编辑:程序博客网 时间:2024/05/29 03:35
                                                                                 红黑树
红黑树(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();}


原创粉丝点击