公众号:CppCoding
红黑树
即使AVL树拥有平衡特性,但它是通过其不断的旋转操作来实现的,最坏情况下将每回溯一层都要进行旋转调整。即数据量大了以后,AVL树的旋转操作就拖慢了插入和删除的时间。
为此引入了红黑树,它具有良好的旋转次数,不至于影响结点插入和删除的时间效率。
红黑树的性质
红黑树优先插入的结点颜色为红色,因为可以不改变以前树中黑色的数量
- 性质1 : 每一个节点是要么是红色要么是黑色
- 性质2 : 根节点必须是黑色
- 性质3 :叶子节点都是黑色(指叶子节点的地址域null为黑色,一般null节点默认颜色是黑色)
- 性质4 : 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
- 性质5 : 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
红黑树的性能
红黑树的时间复杂度为O(logN)
增删性能较好,因为较AVL相比,维持平衡的时间少
函数实现
//红黑树的结点类和红黑树类
template <typename T>
class RedBlackTree{
class Node{
public:
T key;
bool color;//RED 1,BLACK 0;
Node* parent;
Node* leftchild;
Node* rightchild;
Node(T data,bool color,Node* p,Node* l,Node *r):key(data),color(color),parent(p),leftchild(l),rightchild(r){}
};
Node* NIL;
Node* root;
public:
RedBlackTree(T data=0){
NIL=new node(0,false,NULL,NULL,NULL);
root=NIL;
}
Node* GetRoot(){return root;}
Node* Min(Node* x);
Node* FindElement(Node* x,T k);
void LeftRotate(Node* x);
void RightRotate(Node *y);
void RBInsert(T data);
void RBInsertFixup(Node* z);
void RBDelete(T data);
void RBDeleteFixup(Node* x);
};
函数实现
template<typename T>
RedBlackTree<T>::Node* RedBlackTree<T>::GetMin(Node* x){
while(x->leftchild!=NIL)
x=x->leftchild;
return x;
}
//在树中查找一个元素
template<typename T>
RedBlackTree<T>::Node* RedBlackTree<T>::FindElement(Node* x,T k){
if(x==BIL||k==x->key)
return x;
if(k<x->key)
return FindElement(x->leftchild,k);
else
return FindElement(x->rightchild,k);
}
//左旋函数
template <typename T>
void RedBlackTree<T>::LeftRotate(Node* x){
Node* y=x->rightchild;
if(y==NIL) return ;
x->rightchild=y->leftchild;
if(NIL!=y->leftchild){
y->leftchild->parenct=x;
}
y->parent=x->parent;
if(x->parent==NIL)
root=y;
else if(x==x->parent->leftchild)
x->parent->leftchild=y;
else
x->parent->rightchild=y;
y->leftchild=x;
x->parent=y;
}
//结点插入函数
template <typename T>
void RedBlackTree<T>::RBInsert(T data){
Node* x=root;
Node* z=new Node(data,true,NULL,NULL,NULL);
assert(z!=NULL);
Node* y=NIL;
while(x!=NIL){
y=x;
if(z->key<x->key){
if(x->leftchild!=NIL)
x=x->leftchild;
else
break;
}else{
if(x->rightchild!=NIL)
x=x->rightchild;
else
break;
}
}
if(y==NIL)
root=z;
else if(z->key<y->key)
y->leftchild=z;
else
y->rightchild=z;
z->leftchild=NIL;
z->rightchild=NIL;
z->color=true;
RBInsertFixup(z);
}
//插入结点调整树结构
template <typename T>
void RedBlackTree<T>::RBInsertFixup(Node* z){
Node* y=NIL;
while(root!=z&&z->parent->color==true){
if(z->parent==z->parent->parent->leftchild){
y=z->parent->parent->rightchild;
if(y!=NIL&&y->color==true){
z->parent->color=false;
y->color=false;
z->parent->parent->color=true;
z=z->parent->parent;
}else{
if(z==z->parent->rightchild){
z=z->parent;
LeftRotate(z);
}
z->parent->color=false;
z->parent->parent->color=true;
RightRotate(z->parent->parent);
}
}else{
y=z->parent->parent->leftchild;
if(y!=NIL&&y->color==true){
z->parent->color=false;
y->color=false;
z->parent->parent->color=true;
z=z->parent->parent;
}else{
if(z==z->parent->leftchild){
z=z->parent;
RightRotate(z);
}
z->parent->color=false;
z->parent->parent->color=true;
LeftRotate(z->parent->parent);
}
}
}
root->color=false;
}