红黑树

转载 2016年08月31日 11:20:48

前言:

   红黑树是一棵二叉搜索树,它在每个节点上增加了一个存储位来表示节点的颜色,可以是Red或Black。通过对任何一条从根到叶子简单路径上的颜色来约束,红黑树保证最长路径不超过最短路径的两倍,因而近似于平衡。


红黑树的基本概念:

  红黑树是满足下面红黑性质的二叉搜索树
1. 每个节点,不是红色就是黑色的
2. 根节点是黑色的
3. 如果一个节点是红色的,则它的两个子节点是黑色的(不能有连续的两个红节点)
4. 对每个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点。
5. 每个叶子节点都是黑色的(这里的叶子节点是指的NIL节点(空节点))


红黑树的插入写法要根据红黑树插入的各种情况来分析:

ps:cur为当前节点,p为父节点,g为祖父节点,u为叔叔节点
1.第一种情况
cur为红,p为红,g为黑,u存在且为红
则将p,u改为黑,g改为红,然后把g当成cur,继续向上调整。


2.第二种情况
cur为红,p为红,g为黑,u不存在/u为黑
p为g的左孩子,cur为p的左孩子,则进行右单旋转;相反,p为g的右孩子,cur为p的右孩子,则进行左单旋转
p、g变色--p变黑,g变红


3.第三种情况
cur为红,p为红,g为黑,u不存在/u为黑
p为g的左孩子,cur为p的右孩子,则针对p做左单旋转;相反,p为g的右孩子,cur为p的左孩子,则针对p做右单旋转
则转换成了情况2


上面已经把没种情况列出来了,其他相反的情况类似,反过来写一下就行了,具体细节过程见代码,

[cpp] view plain copy
  1. #ifndef __RBTREE_H__  
  2. #define __RBTREE_H__  
  3.   
  4.   
  5. enum colour  
  6. {  
  7.     RED,  
  8.     BLACK,  
  9. };  
  10.   
  11. template<class K,class V>  
  12. struct RBTreeNode  
  13. {  
  14.     int _col;  
  15.     K _key;  
  16.     V _value;  
  17.     RBTreeNode<K, V>* _left;  
  18.     RBTreeNode<K, V>* _right;  
  19.     RBTreeNode<K, V>* _parent;  
  20.   
  21.     RBTreeNode(const K& key, const V& value)  
  22.         :_key(key)  
  23.         , _value(value)  
  24.         , _col(RED)  
  25.         , _left(NULL)  
  26.         , _right(NULL)  
  27.         , _parent(NULL)  
  28.     {}  
  29.   
  30. };  
  31.   
  32.   
  33. template<class K,class V>  
  34. class RBTree  
  35. {  
  36.     typedef RBTreeNode<K, V> Node;  
  37. public:  
  38.     RBTree()  
  39.         :_root(NULL)  
  40.     {}  
  41.   
  42.     bool Insert(const K& key, const V& value)  
  43.     {  
  44.         if (_root == NULL)  
  45.         {  
  46.             _root = new Node(key, value);  
  47.             _root->_col = BLACK;  
  48.             return true;  
  49.         }  
  50.   
  51.         Node* parent = NULL;  
  52.         Node* cur = _root;  
  53.         while (cur)  
  54.         {  
  55.             if (cur->_key > key)  
  56.             {  
  57.                 parent = cur;  
  58.                 cur = cur->_left;  
  59.             }  
  60.   
  61.             else if (cur->_key < key)  
  62.             {  
  63.                 parent = cur;  
  64.                 cur = cur->_right;  
  65.             }  
  66.             else  
  67.                 return false;  
  68.         }  
  69.   
  70.         //插入位置  
  71.         if (parent->_key >key)  
  72.         {  
  73.             cur = new Node(key, value);  
  74.             parent->_left = cur;  
  75.             cur->_parent = parent;  
  76.         }  
  77.         else if (parent->_key < key)  
  78.         {  
  79.             cur = new Node(key, value);  
  80.             parent->_right = cur;  
  81.             cur->_parent = parent;  
  82.         }  
  83.   
  84.         //插入位置以后,如何调整  
  85.         while (cur != _root && parent->_col == RED)  
  86.         {  
  87.             Node* grandfather = parent->_parent;  
  88.             Node* uncle = NULL;  
  89.             //左边的情况  
  90.             if (parent == grandfather->_left)  
  91.             {  
  92.                 //情况一  
  93.                 uncle = grandfather->_right;  
  94.                 if (uncle && uncle->_col == RED)  
  95.                 {  
  96.                     //情况1-> 不需要旋转  
  97.                     if (cur == parent->_left)  
  98.                     {  
  99.                         grandfather->_col = RED;  
  100.                         parent->_col = BLACK;  
  101.                         uncle->_col = BLACK;  
  102.   
  103.                         cur = grandfather;  
  104.                         parent = cur->_parent;  
  105.                     }  
  106.   
  107.                     //需要旋转  
  108.                     else if (cur == parent->_right)  
  109.                     {  
  110.                         RotateL(parent);  
  111.                         grandfather->_col = RED;  
  112.                         parent->_col = BLACK;  
  113.                         uncle->_col = BLACK;  
  114.   
  115.                         cur = grandfather;  
  116.                         parent = cur->_parent;  
  117.                     }  
  118.                       
  119.                 }  
  120.   
  121.                 //情况2,情况3  
  122.                 else if (uncle == NULL || (uncle && uncle->_col == BLACK))  
  123.                 {  
  124.                     //情况3  
  125.                     if (cur == parent->_right)  
  126.                     {  
  127.                         RotateL(parent);  
  128.                     }  
  129.                     parent->_col = BLACK;  
  130.                     grandfather->_col = RED;  
  131.                     RotateR(grandfather);  
  132.                     break;  
  133.                 }  
  134.             }  
  135.             //右边的情况  
  136.             else if (parent == grandfather->_right)  
  137.             {  
  138.                 //情况1  
  139.                 uncle = grandfather->_left;  
  140.                 if (uncle && uncle->_col == RED)  
  141.                 {  
  142.                     //不需要旋转  
  143.                     if (cur == parent->_right)  
  144.                     {  
  145.                         uncle->_col = BLACK;  
  146.                         grandfather->_col = RED;  
  147.                         parent->_col = BLACK;  
  148.   
  149.                         cur = grandfather;  
  150.                         parent = cur->_parent;  
  151.                     }  
  152.   
  153.                     //旋转  
  154.                     else if (cur == parent->_left)  
  155.                     {  
  156.                         uncle->_col = BLACK;  
  157.                         grandfather->_col = RED;  
  158.                         parent->_col = BLACK;  
  159.                         RotateR(parent);  
  160.   
  161.                         cur = grandfather;  
  162.                         parent = cur->_parent;  
  163.                     }  
  164.                 }  
  165.   
  166.                 else if (uncle == NULL || (uncle && uncle->_col == BLACK))  
  167.                 {  
  168.                     //情况2,3  
  169.                     if (cur == parent->_left)  
  170.                     {  
  171.                         RotateR(parent);  
  172.                     }  
  173.                     parent->_col = BLACK;  
  174.                     grandfather->_col = RED;  
  175.                     RotateL(grandfather);  
  176.                     break;  
  177.                 }  
  178.             }  
  179.         }     
  180.         _root->_col = BLACK;  
  181.         return true;  
  182.     }  
  183.   
  184.     bool isRBTree()  
  185.     {  
  186.         int blackNodeNum = 0;  
  187.         int curBlackNodeNum = 0;  
  188.         Node* cur = _root;  
  189.         while (cur)  
  190.         {  
  191.             if (cur->_col == BLACK)  
  192.                 blackNodeNum++;  
  193.   
  194.             cur = cur->_left;  
  195.         }  
  196.         return _isRBTree(_root,blackNodeNum,curBlackNodeNum);  
  197.     }  
  198.   
  199.     void InOrder()  
  200.     {  
  201.         _InOrder(_root);  
  202.     }  
  203.   
  204. protected:  
  205.     bool _isRBTree(Node* root,int blackNodeNum,int curBlackNodeNum)  
  206.     {  
  207.         if (root == NULL)  
  208.             return true;  
  209.   
  210.         if (root->_col == BLACK)  
  211.             curBlackNodeNum++;  
  212.   
  213.         if (blackNodeNum == curBlackNodeNum)  
  214.         {  
  215.             if (root->_parent == NULL)  
  216.                 return true;  
  217.             else if (root->_col == RED && root->_col == root->_parent->_col)  
  218.             {  
  219.                 return false;  
  220.             }  
  221.             else  
  222.             {  
  223.                 return true;  
  224.             }  
  225.         }  
  226.           
  227.         return _isRBTree(root->_left, blackNodeNum, curBlackNodeNum) && _isRBTree(root->_right, blackNodeNum, curBlackNodeNum);  
  228.     }  
  229.   
  230.     void _InOrder(Node* root)  
  231.     {  
  232.         if (root == NULL)  
  233.             return;  
  234.   
  235.         _InOrder(root->_left);  
  236.         cout << root->_key << " ";  
  237.         _InOrder(root->_right);  
  238.     }  
  239.     void RotateL(Node*& parent)  
  240.     {  
  241.         Node* subR = parent->_right;  
  242.         Node* subRL = subR->_left;  
  243.   
  244.         parent->_right = subRL;  
  245.         if (subRL)  
  246.             subRL->_parent = parent;  
  247.   
  248.         subR->_left = parent;  
  249.         subR->_parent = parent->_parent;  
  250.         parent->_parent = subR;  
  251.         parent = subR;  
  252.   
  253.         if (parent->_parent == NULL)  
  254.             _root = parent;  
  255.         else if (parent->_parent->_key > parent->_key)  
  256.         {  
  257.             parent->_parent->_left = parent;  
  258.         }  
  259.   
  260.         else if (parent->_key > parent->_parent->_key)  
  261.         {  
  262.             parent->_parent->_right = parent;  
  263.         }  
  264.     }  
  265.   
  266.     void RotateR(Node*& parent)  
  267.     {  
  268.         Node* subL = parent->_left;  
  269.         Node* subLR = subL->_right;  
  270.   
  271.         parent->_left = subLR;  
  272.         if (subLR)  
  273.             subLR->_parent = parent;  
  274.   
  275.         subL->_right = parent;  
  276.         subL->_parent = parent->_parent;  
  277.         parent->_parent = subL;  
  278.   
  279.         parent = subL;  
  280.   
  281.         if (parent->_parent == NULL)  
  282.             _root = parent;  
  283.   
  284.         else if (parent->_parent->_key > parent->_key)  
  285.         {  
  286.             parent->_parent->_left = parent;  
  287.         }  
  288.   
  289.         else if (parent->_parent->_key < parent->_key)  
  290.             parent->_parent->_right = parent;  
  291.   
  292.     }  
  293.   
  294. protected:  
  295.     Node* _root;  
  296. };  
  297.   
  298.   
  299.   
  300. void testRBtree()  
  301. {  
  302.     RBTree<intint> rbt;  
  303.     int arr[8] = { 2, 5, 12, 16, 18, 26, 3, 1 };  
  304.     for (int i = 0; i < 8; i++)  
  305.     {  
  306.         rbt.Insert(arr[i], i);  
  307.     }  
  308.   
  309.     rbt.InOrder();  
  310.     cout << endl;  
  311.   
  312.     cout << "isRBTree? ->:" << rbt.isRBTree() << endl;  
  313.       
  314. }  
  315.   
  316.   
  317.   
  318. #endif //__RBTREE_H__  

红黑树.pdf

  • 2016年08月03日 22:08
  • 299KB
  • 下载

红黑树的插入与删除说明

  • 2016年04月15日 18:59
  • 581KB
  • 下载

一步一图一代码,一定要让你真正彻底明白红黑树

          一步一图一代码,一定要让你真正彻底明白红黑树作者:July   二零一一年一月九日-----------------------------本文参考:I、  The Art of ...
  • v_JULY_v
  • v_JULY_v
  • 2011年01月09日 10:08
  • 71986

红黑树实现源码

  • 2017年07月22日 22:21
  • 1KB
  • 下载

红黑树原理详解

  • 2012年12月07日 00:39
  • 445KB
  • 下载

红黑树与小根堆性能对比(java)

因为nginx与libevent采用了不同的数据结构来维护超时事件,其中nginx采用了红黑树,libevent采用的是小根堆,所以一直比较好奇,这两种数据结构谁在这种应用场景下更合适(当做优先权队列...

彻底明白红黑树

  • 2013年09月17日 20:13
  • 12.95MB
  • 下载

红黑树求解C代码

  • 2013年04月05日 22:36
  • 2KB
  • 下载

红黑树(Red Black Tree)- 对于 JDK TreeMap的实现

介绍另一种平衡二叉树:红黑树(Red Black Tree),红黑树由Rudolf Bayer于1972年发明,当时被称为平衡二叉B树(symmetric binary B-trees),1978年被...

红黑树实现java代码

  • 2015年11月01日 02:32
  • 5KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:红黑树
举报原因:
原因补充:

(最多只允许输入30个字)