RBTree红黑树
来源:互联网 发布:北外网络教育多少钱 编辑:程序博客网 时间:2024/05/30 04:47
对平衡的要求低
二叉搜索树
性质:
1.每个节点不是红的就是黑的
2.根节点是黑的
3.若一个节点是红的,则它的两个子节点是黑的(即不能出现两个连续的红的)
4.每条路径的黑节点的数量相等
5.每个叶子节点都是黑的(叶子节点:NIL节点,空节点)
最长路径不超过最短路径的两倍
调整情况
cur是刚插入的节点
1.叔叔存在,且为红
根是红色的,可能会不满足RBTree树的规则(eg:出现连续的两个红色),所以还需要继续向上调整
2.叔叔不存在或者叔叔存在且为黑
然后接着第三种情况
3.
根是黑色的,不用再继续向上调整了
左旋
右旋
代码:
#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;}
结果:
本文出自 “追寻内心的声音” 博客,请务必保留此出处http://ljy789.blog.51cto.com/10697684/1829933
0 0
- 红黑树-RBTree
- RBTree红黑树
- RBTree----红黑树
- RBTree(红黑树)
- 红黑树--RBTree
- 红黑树【RBTree】
- 红黑树(RBtree)
- RBTree-红黑树的实现
- 【c++/数据结构】红黑树-RBTree
- 数据结构-红黑树(RBTree)
- 【数据结构】中的红黑树-RBTree
- 红黑树(RBTree)
- RBTree(红黑树)
- 6.Nginx红黑树rbtree
- RBTree——红黑树
- RBTree
- RBTree
- RBTree
- HDU 1408 盐水的故事
- 遍历二叉树
- hdu1432 Lining Up --判断点在一条线上的个数
- length,length(),size()区别
- Android中的Toolbar详解
- RBTree红黑树
- C基础(21——25)
- C基础(26——30)
- C++ STL 之 BitSet
- Head First设计模式整理
- 通过Tomcat配置虚拟目录传输文件方便测试Android应用
- String类的获取功能
- 高质量程序好文分享之王垠《编程的智慧》
- ImageView 无法显示图片问题解决办法