亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

二叉搜索樹—RBTree(紅黑樹)

發布時間:2020-06-20 04:40:03 來源:網絡 閱讀:868 作者:無心的執著 欄目:編程語言


       紅黑樹又稱二叉搜索樹,它主要是通過紅和黑兩種顏色(red、black)來標識節點。通過對任何一條從根節點到葉子節點路徑上的節點顏色進行約束,紅黑樹保證最長路徑不超過最短路徑的兩倍,所以說:紅黑樹是近似于平衡的



■下面是紅黑樹的主要特點:

        (1)紅黑樹的根節點是黑色的。

        (2)紅黑樹中若一個節點是紅色的,則它的兩個子節點必須是黑色的。

        (3)紅黑樹中從該節點到后代葉節點的路徑上,黑色節點數目是相同的。



       ◆紅黑樹的應用:

                 C++庫、linux內核、java庫等


       ◆紅黑樹與AVL樹的區別:

                  紅黑樹和AVL樹都是高效的平衡搜索樹,時間復雜度都是O(lgN);

                  紅黑樹對平衡的要求不是特別高,它只需要滿足最長路徑不超過最短路徑的兩倍,所以性能相對較高。



■下面是紅黑樹中節點結構:

enum color      //枚舉節點的兩種顏色
{
     RED,
     BLACK,
};

template <class K, class V>
struct RBTreeNode
{
     color _col;
     RBTreeNode<K, V>* _left;
     RBTreeNode<K, V>* _right;
     RBTreeNode<K, V>* _parent;
     K _key;
     V _value;
     
     RBTreeNode(const K& key, const V& value)
          :_key(key)
          , _value(value)
          , _left(NULL)
          , _right(NULL)
          , _parent(NULL)
          , _col(RED)          //顏色必須插入的是紅色,因為要保證黑色節點的個數是平衡的
     { }
};



■下面分析紅黑樹的插入情況:

(1)


二叉搜索樹—RBTree(紅黑樹)




(2)


二叉搜索樹—RBTree(紅黑樹)


(3)


二叉搜索樹—RBTree(紅黑樹)


■下面是主要的代碼:

#pragma once
//實現紅黑樹的基本功能
/*
1.紅黑樹中的節點只能是紅色或者黑色
2.紅黑樹的根節點為黑色
3.紅黑樹的左、右子樹的黑色節點個數是相同的
4.紅黑樹中紅色節點的兩個孩子節點必須都為黑色節點
*/

enum color      //枚舉節點的兩種顏色
{
     RED,
     BLACK,
};

template <class K, class V>
struct RBTreeNode
{
     color _col;
     RBTreeNode<K, V>* _left;
     RBTreeNode<K, V>* _right;
     RBTreeNode<K, V>* _parent;
     K _key;
     V _value;
     
     RBTreeNode(const K& key, const V& value)
          :_key(key)
          , _value(value)
          , _left(NULL)
          , _right(NULL)
          , _parent(NULL)
          , _col(RED)          //顏色必須插入的是紅色,因為要保證黑色節點的個數是平衡的
     { }
};

template <class K, class V>
class RBTree
{
     typedef RBTreeNode<K, V> Node;
public:
     RBTree()
          :_root(NULL)
     {}
     
     bool Insert(const K& key, const V& value)
     {
          if (_root == NULL)      //根節點為空的情況,必須將根節點置為黑色
          {
               _root = new Node(key, value);
               _root->_col = BLACK;
               return true;
          }
          Node* cur = _root;
          Node* parent = NULL;
          while (cur)
          {
               if (cur->_key < key)
               {
                    parent = cur;
                    cur = cur->_right;
               }
               else if (cur->_key > key)
               {
                    parent = cur;
                    cur = cur->_left;
               }
               else
               {
                    break;
               }
          }
          
          //尋找到數據該插入的位置
          if (parent->_key < key)
          {
               Node* tmp = new Node(key, value);
               parent->_right = tmp;
               tmp->_parent = parent;
          }
          else if (parent->_key > key)
          {
               Node* tmp = new Node(key, value);
               parent->_left = tmp;
               tmp->_parent = parent;
          }
          
      //處理(如果父節點為黑色,則不用對樹進行調整,樹保持紅黑樹的狀態)
          while(cur != _root && parent->_col == RED)
          //插入的不是根節點,且父節點的顏色為紅
          {
               Node* grandFather = parent->_parent;
               if (parent == grandFather->_left)
               {
                    Node* uncle = grandFather->_right;
                    //情況一:需要將祖父節點置為紅色,將父親節點和叔叔節點置為黑色,
                    //下次直接從祖父節點向上進行調整
                    if (uncle != NULL && uncle->_col == RED)    
                    {
                     grandFather->_col = RED;
                     parent->_col = BLACK;
                     uncle->_col = BLACK;
                     cur = grandFather;
                     parent = cur->_parent;
                    }
                    else
                    {
                     //情況二:需要先進行右單旋,然后將父親節點置為黑色,祖父節點置為紅色
                      //情況三:需要先進行左單旋,然后就會轉化為情況二
                     if (cur == parent->_right && parent->_right != NULL)  //情況三左、右
                     {
                      _RotateL(parent);
                     }
                     parent->_col = BLACK;     
                     grandFather->_col = RED;
                     _RotateR(grandFather);
                    
                    }
               }
               else     //父親節點為祖父節點的右節點
               {
                    Node* uncle = grandFather->_left;
                    //情況一:需要將祖父節點置為紅色,將父親節點和叔叔節點置為黑色,
                    //下次直接從祖父節點向上進行調整
                    if (uncle != NULL && uncle->_col == RED)
                    {
                         grandFather->_col = RED;
                         parent->_col = BLACK;
                         uncle->_col = BLACK;
                         cur = grandFather;
                         parent = cur->_parent;
                    }
                    else
                    {
                     //情況二:需要先進行左單旋,然后將父親節點置為黑色,祖父節點置為紅色
                     //情況三:需要進行右單旋,然后就會轉化為情況二
                         if (cur == parent->_left && parent->_left != NULL)//情況三右、左
                         {
                              _RotateR(parent);
                         }
                         parent->_col = BLACK;
                         grandFather->_col = RED;
                         _RotateL(grandFather);
                    }
               }
          }
          _root->_col = BLACK;
          return true;
     }

     void InOrder()
     {
          _InOrder(_root);
          cout << endl;
     }
     
     bool Check()     //檢查是否為紅黑樹
     {
          int countBlack = 0;
          Node* cur = _root;
          while (cur->_left != NULL)    //統計一條路徑上的黑色節點的數目
          {
               if (cur->_col == BLACK)
               {
                    countBlack++;
               }
               cur = cur->_left;
          }
          return _Check(_root, 0, countBlack);
     }
     
protected:
     bool _Check(Node* root, int blackNum, int curBalanceNum)
     {
          if (root == NULL)
          {
               return false;
          }
          if (root->_parent != NULL && root->_col == BLACK)   
          {
               if (root->_parent->_col == RED)
               {
                    return true;
               }
          }
          if (root->_left == NULL && root->_right == NULL)     //遞歸到葉子節點是的黑色節點數目是否相等
          {
               if (blackNum == curBalanceNum)
               {
                    return true;
               }
               else
               {
                    return false;
               }
          }
          return _Check(root->_left, blackNum++, curBalanceNum)
           && _Check(root->_right, blackNum++, curBalanceNum);
     }

     void _InOrder(Node* root)
     {
          if (root == NULL)
          {
               return;
          }
          _InOrder(root->_left);
          cout << root->_key <<":"<<root->_col<<endl;
          _InOrder(root->_right);
     }

     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;
          parent->_parent = SubR;
          parent = SubR;
          if (parent->_parent == NULL)     //parent為根節點的情況
          {
               _root = parent;
          }
          else                             //parent不為根節點
          {
               Node* ppNode = parent->_parent;
               if (ppNode->_key > parent->_key)
               {
                    ppNode->_left = parent;
               }
               else
               {
                    ppNode->_right = parent;
               }
          }
     }

     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;
          parent->_parent = SubL;
          parent = SubL;
          if (parent->_parent == NULL)     //parent為根節點的情況
          {
               _root = parent;
          }
          else                             //parent不為根節點
          {
               Node* ppNode = parent->_parent;
               if (ppNode->_key > parent->_key)
               {
                    ppNode->_left = parent;
               }
               else
               {
                    ppNode->_right = parent;
               }
          }
     }
     
protected:
     Node* _root;
};

void Test()
{
     RBTree<int, int> ht;
     ht.Insert(5, 1);
     ht.Insert(9, 1);
     ht.Insert(3, 1);
     ht.Insert(1, 1);
     ht.Insert(8, 1);
     ht.Insert(2, 1);
     ht.Insert(4, 1);
     ht.Insert(6, 1);
     ht.Insert(7, 1);
     
     ht.InOrder();
     cout<<ht.Check()<<endl;
}






向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

富顺县| 剑河县| 岳普湖县| 临朐县| 高清| 灵山县| 中西区| 雅江县| 南木林县| 涪陵区| 平江县| 盱眙县| 阿克陶县| 宁德市| 固始县| 分宜县| 灵川县| 凉城县| 岑巩县| 阿图什市| 东海县| 沂南县| 灵宝市| 贞丰县| 陆丰市| 简阳市| 漳浦县| 灌云县| 陈巴尔虎旗| 河南省| 宣化县| 都匀市| 淮阳县| 西乌| 九龙坡区| 吉林省| 无极县| 平利县| 泰安市| 且末县| 新沂市|