红黑树的实现

红黑树(Red Black Tree) 是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组

红黑树的五条性质:(特别重要)

1.节点是红色或黑色

2.根节点是黑色

3. 每个叶节点(NIL节点,空节点)是黑色的,又称为外节点

4.如果一个节点是红色的,则他的两个子节点都是黑色的

5.对每个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点

注意:叶节点,也即外节点,本身没有任何信息,只是标示节点的终结,所以,其key域没有任何意义,但其color域为黑色。(这个规定使得删除内节点操作变得简单便利)

首先定义红黑树类以及其成员方法:

#ifndef RBT_H_20150408
#define RBT_H_20150408
#include<vector>
using std::vector;
class RBT{
	struct Node{
		Node();
		Node(int,bool,Node*,Node*,Node*);
		int value;
		bool isBlack;
		Node *left;
		Node *right;
		Node *father;
	};

	Node *root;
	Node *NIL;
	void left_roll(Node *);
	void right_roll(Node *);
	void in_fixup(Node *);
	void de_fixup(Node *);
public:
	RBT();
	RBT(vector<int>);
	~RBT();
	Node *getroot()const;
	void insert(int);
	void DelEle(Node*,int );
	void RBdelete(Node *);
	Node *Tree_Successor(Node *);
};


#endif

成员方法的实现

#include<iostream>
#include<vector>
#include "RBT.h"
using namespace std;
RBT::Node::Node():value(-1),isBlack(true),left(NULL),right(NULL),father(NULL){}
RBT::Node::Node(int v,bool isBlack,Node* left,Node* right,Node* father):value(v),isBlack(isBlack),left(left),right(right),father(father){}
RBT::RBT(){
	NIL=new Node();
	root=NIL;
}
RBT::RBT(vector<int> ivec){
	NIL=new Node();
	root=NIL;
	for(size_t i=0;i<ivec.size();++i)
		insert(ivec.at(i));
}
RBT::~RBT(){} 
void RBT::left_roll(Node *x){
	if(x==NIL||x->right==NIL)
		return;
	Node *y=x->right;
	x->right=y->left;
	if(y->left!=NIL)
		y->left->father=x;
	y->father=x->father;
	if(root==x)
		root=y;
	else if(x==x->father->left)
		x->father->left=y;
	else  
		x->father->right=y;
	y->left=x;
	x->father=y;
}

void RBT::right_roll(Node *x){
	if(x==NIL||x->left==NIL)
		return;
	Node *y=x->left;
	x->left=y->right;
	if(y->right!=NIL)
		y->right->father=x;
	y->father=x->father;
	if(root==x)
		root=y;
	else if(x==x->father->left)
		x->father->left=y;
	else
		x->father->right=y;
	y->right=x;
	x->father=y;
}

void RBT::insert(int v){
	Node *y=NIL;
	Node *x=root;
	Node *newNode=new Node(v,false,NIL,NIL,NIL);
	/*if(root==NIL){
		root=x;
		newNode->isBlack=true;
		return;
	}*/
	while(x!=NIL){
		y=x;
		if(v<x->value)
			x=x->left;
		else
			x=x->right;
		}
	newNode->father=y;
	if(y==NIL){
		root=newNode;
	}else if(v<y->value){
		y->left=newNode;
	}else{
		y->right=newNode;
	}
	in_fixup(newNode);
}

void RBT::in_fixup(Node *z){
	Node *y=NIL;

	while(z->father!=NIL&&z->father->father!=NIL&&z->father->isBlack==false){//父节点是红色
		if(z->father==z->father->father->left){
				y=z->father->father->right;//叔叔
				if(y!=NIL&&y->isBlack==false){//case 1,uncle is red;
					z->father->isBlack=true;
					y->isBlack=true;
					z->father->father->isBlack=false;
					z=z->father->father;
				}else{
					if(z->father->right==z){//case 2:z as right child
						z=z->father;
						left_roll(z);
					}
					z->father->isBlack=true;//case 3:
					z->father->father->isBlack=false;
					right_roll(z->father->father);
				}
		}else{
			y=z->father->father->left;
			if(y!=NIL&&y->isBlack==false){
				z->father->isBlack=true;
				y->isBlack=true;
				z->father->father->isBlack=false;
				z=z->father->father;
			}else{
				if(z->father->left==z){
					z=z->father;
					right_roll(z);
				}
				z->father->isBlack=true;
				z->father->father->isBlack=false;
				left_roll(z->father->father);
		}
	}
	}
	root->isBlack=true;
}
RBT::Node* RBT::Tree_Successor(Node *p){
	Node *x,*left;
	if(p->right!=NIL){
		x=p->right;
		while((left=x->left)!=NIL)
			x=left;
	}
	return x;
}
void RBT::DelEle(Node *root,int data){
	if(root==NULL){
		cout<<"Empty tree";
		return;
	}
	if(root->value==data)
		RBdelete(root);
	else if(data<root->value)
		DelEle(root->left,data);
	else
		DelEle(root->right,data);
}
void RBT::RBdelete(Node *z){
	Node *y=NIL;
	Node *x=NIL;
	//问题转换为删除只有一个孩子的节点(或没有孩子)
	if(z->left==NIL||z->right==NIL){
		y=z;
	}else{
		y=Tree_Successor(z);
	}
	//以上找出要删除的节点
	if(y->left!=NIL)
		x=y->left;
	else 
		x=y->right;//主要基于Tree_Successor(z)的方式,有两种:先右然后左到底;先左右到底
	x->father=y->father;//
	if(y==root)
		root=x;
	else if(y==y->father->left)
		y->father->left=x;
	else 
		y->father->right=x;
	if(z!=y)
		z->value=y->value;
	if(y->isBlack==true)//
		de_fixup(x);
	delete y;
}
void RBT::de_fixup(Node *x){
	Node *w=NIL;
	while(x!=root&&x->isBlack==true){
		if(x==x->father->left){
			w=x->father->right;
			if(w->isBlack==false){
				w->isBlack=true;
				x->father->isBlack=false;
				left_roll(x->father);
				w=x->father->right;
			}
			if(w->left->isBlack==true&&w->right->isBlack==true){
				w->isBlack=false;
				x=x->father;
			}else{
				if(w->right->isBlack==true){
					w->left->isBlack=true;
					w->isBlack=false;
					right_roll(w);
					w=x->father->right;
				}
				w->isBlack=x->father->isBlack;
				x->father->isBlack=true;
				w->right->isBlack=true;
				left_roll(x->father);
				x=root;
			}
		}else{
			w=x->father->left;
			if(w->isBlack==false){
				w->isBlack=true;
				x->father->isBlack=false;
				right_roll(x->father);
				w=x->father->left;
			}
			if(w->left->isBlack==true&&w->right->isBlack==true){
				w->isBlack=false;
				x=x->father;
			}else{
				if(w->left->isBlack==true){
					w->right->isBlack=true;
					w->isBlack=false;
					left_roll(w);
					w=x->father->right;
				}
				w->isBlack=x->father->isBlack;
				x->father->isBlack=true;
				w->left->isBlack=true;
				right_roll(x->father);
				x=root;
			}
		}
	}
	x->isBlack=true; 
}
RBT::Node* RBT::getroot()const{
	return root;
}


简单测试函数

#include<iostream>
#include<vector>
#include"RBT.h"
using namespace std;
int main(){
	vector<int> ivec;
	RBT myrbt;
	int a[]={11,7,1,2,5,4,8,14,15};
	//int a[]={2,11,14,7,15,5,8,4};
	/*for(int i=0;i<8;i++)
		ivec.push_back(a[i]);*/
	for(int i=0;i<9;i++)
		myrbt.insert(a[i]);
	myrbt.DelEle(myrbt.getroot(),1);
	myrbt.getroot();
	return 0;
}


最近时间有限,暂时就这么多吧,对于插入和删除操作没有作任何描述……对于红黑树来说,这两个操作还是比较麻烦的(涉及到完成操作后对树的调整)。以后会将删除和插入操作详细讲解一下。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值