一、红黑树
红黑树(Red Black Tree) 是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组。
可以保证最长路径不超过最短路径的2倍,近似平衡。
二、性质
性质1. 节点是红色或黑色。
性质2. 根节点是黑色。
性质3 每个叶节点(NIL节点,空节点)是黑色的。
性质4 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
性质5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
三、实现代码:
(1) 插入新的节点:
第一种情况:cur(新)为红,p(父)为红,g(祖)为黑,u(叔)存在且为红;-------->p变为黑,g为红,u为黑
第二种情况:cur(新)为红,p(父)为红,g(祖)为黑,u(叔)不存在或者u为黑;-------->p变为黑,g为红,u为黑
第三种情况:cur(N)为红,p为红,g为黑,u不存在或者u为黑;------>旋转为第二种情况,交换N和P节点。
(2)判断是否平衡
判断是否出现连续红色的情况;
判断各支路是否黑色节点相等;
(3)实现如下:
#pragma once #include<iostream> using namespace std; enum color{BLACK,REB}; template<class K,class V> struct RBTreeNode { RBTreeNode(K key,V value) :_left(NULL) ,_right(NULL) ,_parent(NULL) ,_key(key) ,_value(value) ,_col(REB) {} RBTreeNode<K,V>* _left; RBTreeNode<K,V>* _right; RBTreeNode<K,V>* _parent; K _key; V _value; color _col; }; template<class K,class V> class RBTree { typedef RBTreeNode<K,V> Node; public: RBTree() :_root(NULL) {} void Insert(K key,V value) { if(_root==NULL) { _root=new Node(key,value); _root->_col=BLACK; return; } 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; } if(parent->_key>key) { parent->_left=new Node(key,value); parent->_left->_parent=parent; cur=parent->_left; } else if(parent->_key<key) { parent->_right=new Node(key,value); parent->_right->_parent=parent; cur=parent->_right; } //_root->_col=BLACK; //第一种情况:cur为红,p为红,g为黑,u不存在或者为红 while(cur!=_root&&parent->_col==REB) { Node* grandfather=parent->_parent; if(grandfather->_left==parent) { Node* uncle=grandfather->_right; if(uncle&&uncle->_col==REB) { parent->_col=uncle->_col=BLACK; grandfather->_col=REB; // cur=grandfather; parent=cur->_parent; } else { if(cur==parent->_right) //第三种情况: { RotateL(parent);//以parent为轴左旋 swap(cur,parent); } parent->_col=BLACK; //第二种情况: grandfather->_col=REB; RotateR(grandfather); //以grandfather为轴右旋 break; } } else { Node* uncle=grandfather->_left; if(uncle&&uncle->_col==REB) { parent->_col=uncle->_col=BLACK; grandfather->_col=REB; cur=grandfather; parent=cur->_parent; } else { if(parent->_left==cur) //第三种情况 { RotateR(parent); swap(parent,cur); } //第二种情况 parent->_col=BLACK; grandfather->_col=REB; RotateL(grandfather); break;//以grandfather为轴左旋 } } } _root->_col=BLACK; } bool IsBalance() { int key=0; Node* cur=_root; while(cur) { if(cur->_col==BLACK) { key++; } cur=cur->_left; } int count=0; return _IsBalance(_root,key,count); } void InOrder() { _InOrder(_root); } private: void RotateL(Node* parent) { Node* subR=parent->_right; Node* subRL=subR->_left; Node* ppNode=parent->_parent; subR->_left=parent; parent->_parent=subR; if(subRL) { parent->_right=subRL; subRL->_parent=parent; } else parent->_right=NULL; if(ppNode&&ppNode->_left==parent) { ppNode->_left=subR; subR->_parent=ppNode; } else if(ppNode&&ppNode->_right==parent) { ppNode->_right=subR; subR->_parent=ppNode; } else if(ppNode==NULL) { _root=subR; subR->_parent=NULL; } } void RotateR(Node* parent) { Node* subL=parent->_left; Node* subLR=subL->_right; Node* ppNode=parent->_parent; subL->_right=parent; parent->_parent=subL; if(subLR) { subLR->_parent=parent; parent->_left=subLR; } else parent->_left=NULL; if(ppNode&&ppNode->_left==parent) { ppNode->_left=subL; subL->_parent=ppNode; } else if(ppNode&&ppNode->_right==parent) { ppNode->_right=subL; subL->_parent=ppNode; } else if(ppNode==NULL) { _root=subL; subL->_parent=NULL; } } void _InOrder(Node* root) { if(root==NULL) { return; } _InOrder(root->_left); cout<<root->_key<<"->"; _InOrder(root->_right); } bool _IsBalance(Node* root,int key,int count) { if(root==NULL) { return true; } if(root->_col==REB&&root->_parent->_col==REB) { cout<<"连续红色"<<endl; return false; } if(root->_col==BLACK) { count++; } if(root->_left==NULL&&root->_right==NULL&&key!=count) { cout<<"黑色不等"<<endl; return false; } return _IsBalance(root->_left,key,count)&&_IsBalance(root->_right,key,count); } private: Node* _root; };
#include"RBTree.h" int main() { RBTree<int,int> t1; int a[]={1,2,3,4,5,6,7,8,9}; for(int i=0;i<(sizeof(a)/sizeof(a[0]));i++) { //cout<<a[i]<<t1.IsBalance()<<endl; t1.Insert(a[i],i); cout<<a[i]<<t1.IsBalance()<<endl; //cout<<a[i]<<endl; } t1.InOrder(); cout<<t1.IsBalance()<<endl; system("pause"); return 0; }
4、结果: