1. 程式人生 > >RBTree(紅黑樹)

RBTree(紅黑樹)

#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();
}