红黑树

公众号: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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值