RBTree红黑树

来源:互联网 发布:北外网络教育多少钱 编辑:程序博客网 时间:2024/05/30 04:47

对平衡的要求低

二叉搜索树

性质:

1.每个节点不是红的就是黑的

2.根节点是黑的

3.若一个节点是红的,则它的两个子节点是黑的(即不能出现两个连续的红的)

4.每条路径的黑节点的数量相等

5.每个叶子节点都是黑的(叶子节点:NIL节点,空节点

最长路径不超过最短路径的两倍

wKiom1eWPvOSZSC3AAAN3M2VS5M422.pngwKioL1eWPwqQ3d34AAAnud6Ifns792.png

调整情况

cur是刚插入的节点

1.叔叔存在,且为红

wKiom1eWPyrg-MQZAAA85U_X02g842.png

根是红色的,可能会不满足RBTree树的规则(eg:出现连续的两个红色),所以还需要继续向上调整

2.叔叔不存在或者叔叔存在且为黑

wKioL1eWP0yimf0OAAAyM8q1K4Q517.png

然后接着第三种情况

3.

wKioL1eWP23QjmmhAAAw0Cpy0BA323.png

wKiom1eWP4nxqwV-AAAjLWK6dNw400.png

根是黑色的,不用再继续向上调整了

左旋

wKioL1eWP6bRmEcpAAAswjbowQk458.png

右旋

wKiom1eWP8GgUyQWAAA4hAfOlT4956.png

代码:

#include <iostream>using namespace std;enum color{                 RED,                 BLACK};template<class K,class V>struct RBTreeNode{                 K _key;                 V _value;                 RBTreeNode<K ,V>* _parent;                 RBTreeNode<K ,V>* _left;                 RBTreeNode<K ,V>* _right;                 color _col;                RBTreeNode( const K & key,const V& value)  //构造函数                                :_key( key)                                ,_value( value)                                ,_parent( NULL)                                ,_left( NULL)                                ,_right( NULL)                                ,_col( RED)  //节点默认颜色:红,因为不会影响插入                {}};template<class K,class V>class RBTree{                 typedef RBTreeNode <K,V> Node;private:                 Node* _root;public:                RBTree()  //构造函数                                :_root( NULL)                {}                 bool Insert(const K& key,const V& value)                {                                 if(_root==NULL )                                {                                                _root= new Node (key,value);                                }                                 else                                {                                                 Node* cur=_root;                                                 Node* parent=NULL ;                                                 while(cur)                                                {                                                                parent=cur;                                                                                                                                if(cur->_key>key )  //插左                                                                {                                                                                cur=cur->_left;                                                                }                                                                 else if (cur->_key<key)  //插右                                                                {                                                                                cur=cur->_right;                                                                }                                                                 else                                                                {                                                                                 return false ;                                                                }                                                }                                                cur= new Node (key,value);                                                 if(parent->_key>key )  //插左                                                {                                                                parent->_left=cur;                                                }                                                 else  //插右                                                {                                                                parent->_right=cur;                                                }                                                cur->_parent=parent;                                                 //调整                                                 while(cur!=_root && parent->_col==RED)  //parent为红,则包含着其父为黑                                                {                                                                 Node* grandfather=parent->_parent;                                                                 if(grandfather->_left==parent)                                                                {                                                                                 Node* uncle=grandfather->_right;                                                                                 if(uncle && uncle->_col==RED)  //调整情况1                                                                                {                                                                                                parent->_col= BLACK ;                                                                                                uncle->_col= BLACK ;                                                                                                grandfather->_col= RED ;                                                                                                 //因为把根调整成了红色,可能会影响RBTree的规则,所以要继续上调                                                                                                cur=grandfather;                                                                                                parent=cur->_parent;                                                                                }                                                                                 else                                                                                {                                                                                                 //调整情况2,先变化成情况3                                                                                                 if(cur==parent->_right)                                                                                                {                                                                                                                RotateL(parent);  //左旋                                                                                                                swap(parent,cur);                                                                                                }                                                                                                 //调整情况3                                                                                                parent->_col= BLACK ;                                                                                                grandfather->_col= RED ;                                                                                                RotateR(grandfather);  //右旋                                                                                                 break;  //根是黑色的,不用再继续向上调整了                                                                                }                                                                }                                                                 else  //grandfather->_right==parent,内容大体同上                                                                {                                                                                 Node* uncle=grandfather->_left;                                                                                 if(uncle && uncle->_col==RED)  //调整情况1                                                                                {                                                                                                parent->_col= BLACK ;                                                                                                uncle->_col= BLACK ;                                                                                                grandfather->_col= RED ;                                                                                                 //继续上调                                                                                                cur=grandfather;                                                                                                parent=cur->_parent;                                                                                }                                                                                 else                                                                                {                                                                                                 //调整情况2,先变化成情况3                                                                                                 if(cur==parent->_left)                                                                                                {                                                                                                                RotateR(parent);  //右旋                                                                                                                swap(parent,cur);                                                                                                }                                                                                                 //调整情况3                                                                                                parent->_col= BLACK ;                                                                                                grandfather->_col= RED ;                                                                                                RotateL(grandfather);  //左旋                                                                                                 break;  //根是黑色的,不用再继续向上调整了                                                                                }                                                                }                                                }  //调整结束                                }                                _root->_col= BLACK;                                 return true ;                }                 Node* Find(const K& key)                 {                              Node* cur=_root;                              while(cur)                              {                                              if(cur->_key>key )                                                              cur=cur->_left;                                              else if (cur->_key<key)                                                              cur=cur->_right;                                              else  //cur->_key==key,find it!                                                              return cur;                              }                              return NULL ;                 }                 bool Isbalance()                 {                              if(_root==NULL )                                              return true ;                              if(_root->_col==RED )                                              return false ;                              int k=0;  //计算黑节点的个数,作为一个基准值                              Node* cur=_root;                                                           while(cur)                              {                                              if(cur->_col==BLACK )                                                              k++;                                              cur=cur->_left;                              }                              int count=0;                              return _Isbalance(_root,k,count);                 }                 void InOrder()  //中序遍历输出                 {                              _InOrder(_root);                                                                                                                  cout<<endl;                 }protected:                 void RotateL(Node * parent)                {                                 Node* subR=parent ->_right;                                 Node* subRL=subR->_left;                                 parent->_right=subRL;                                 if(subRL)                                {                                                subRL->_parent= parent ;                                }                                subR->_left= parent;                                 Node* ppNode=parent ->_parent;                                 parent->_parent=subR;                                 if(ppNode==NULL )                                {                                                subR->_parent= NULL ;                                                _root=subR;                                }                                 else                                {                                                 if(ppNode->_left==parent )                                                                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;                                 Node* ppNode=parent ->_parent;                                 parent->_parent=subL;                                 if(ppNode==NULL )                                {                                                subL->_parent= NULL ;                                                _root=subL;                                }                                 else                                {                                                 if(ppNode->_left==parent )                                                                ppNode->_left=subL;                                                 else                                                                ppNode->_right=subL;                                                subL->_parent=ppNode;                                }                }                 bool _Isbalance(Node * root,const int k,int count)                 {                              if(root ==NULL)                                              return false ;                              if(root ->_col==RED && root->_parent->_col==RED )  //连续的红节点                              {                                              cout<<"连续输出红节点" <<endl;                                              return false ;                              }                              if(root ->_col==BLACK)                                              count++;  //记录出现的黑节点的数                              if(root ->_left==NULL && root->_right==NULL && k!=count)                              {                                              cout<<"黑色节点数不等" <<endl;                                              return false ;                              }                              return _Isbalance(root ->_left,k,count)+_Isbalance( root->_right,k ,count);                 }                 void _InOrder(Node * root)                 {                              if(root ==NULL)                                              return;                              _InOrder( root->_left);                              cout<< root->_key<<" " ;                              _InOrder( root->_right);                 }};void test(){                 RBTree<int ,int> rbt;                 int a[]={27,20,30,18,25,28,40,23,35,29};                 for(int i=0;i<sizeof(a)/ sizeof(a[0]);i++)                {                                rbt.Insert(a[i],i);                }                 rbt.InOrder();                 rbt.Isbalance();}int main(){                test();                system( "pause");                 return 0;}

结果:

wKioL1eWQAajxv3vAAAJN38wTBQ030.png

wKiom1eWQBrDBj2vAAAqK8YDVQQ646.png



本文出自 “追寻内心的声音” 博客,请务必保留此出处http://ljy789.blog.51cto.com/10697684/1829933

0 0
原创粉丝点击