红黑树

C++实现红黑树,红黑树的讲解可以参见维基百科,相当仔细,http://zh.wikipedia.org/zh/红黑树,下面是代码。
/*红黑树的结点定义*/

//红黑树颜色
#pragma once

#include "RBTree.h"

enum rb{RED=0,BLACK};

//红黑树结点
class Node{
	friend class RBTree;
	int value;    //结点值
	rb color;     
	Node *lchild,*rchild,*parent;
	//默认构造函数
	Node(int va=0,Node* nil=0,rb co=RED):value(va),color(co),lchild(nil),rchild(nil),parent(0){}
	//返回祖父结点的指针函数
	Node* grandParent(){
		if(parent==0)
			return 0;
		return parent->parent;
	}
	//返回叔父结点的指针
	Node* uncle(){
		Node* gParent=grandParent();
		if(gParent==0)
			return 0;
		if(parent==gParent->lchild)
			return gParent->rchild;
		else
			return gParent->lchild;
	}
	//返回兄弟结点的指针
	Node* sibling(){
		if(parent->lchild==this)
			return parent->rchild;
		else
			return parent->lchild;
	}
	//返回结点的颜色
	//rb col(){return color;}
};



/*红黑树的类文件,实现红黑树,在节点的插入和删除过程中,保持
*红黑树的性质,仅作为红黑树的学习之用
*2014.9.14 
*/

#pragma once

#include "Node.h"

class RBTree
{
public:
	RBTree(void):root(0),NIL(new Node(0,0,BLACK)){};
	~RBTree(void);
	void insert(int);
	void deleteVal(int);   //删除关键字结点
	void display();   //显示红黑树
private:
	Node *root,*NIL;   
	void rotate_right(Node*);     //右旋转
	void rotate_left(Node*);      //左旋转
	void show(Node*);  //递归输出树
	void destory();    //销毁树
	void desNode(Node*);  //销毁结点
	int search(int,Node* &);      //查找红黑树中的元素
	void insertLoc(Node*,int);     //插入结点
	void insertCase(Node*);     //调整使仍为红黑树
	Node* getSmall(Node*);    //获得右子树的最小关键字的结点
	void swap(Node*,Node*);   //子树替代
	void deleteNode(Node*);   //删除结点
	void deleteCase(Node*,rb); //调整使称为红黑树
};


#include "RBTree.h"
#include <iostream>

using namespace std;

RBTree::~RBTree(void)
{
	destory();
}

void RBTree::rotate_right(Node* n){
	if(n->parent!=0 && n->parent->lchild==n)
		n->parent->lchild=n->lchild;
	else if(n->parent!=0 && n->parent->rchild==n)
		n->parent->rchild=n->lchild;
	else
		root=n->lchild;
	n->lchild->parent=n->parent;
	n->parent=n->lchild;
	n->lchild=n->lchild->rchild;
	if(n->lchild!=NIL)
		n->lchild->parent=n;
	n->parent->rchild=n;
}

void RBTree::rotate_left(Node* n){
	if(n->parent!=0 && n->parent->lchild==n)
		n->parent->lchild=n->rchild;
	else if(n->parent!=0 && n->parent->rchild==n)
		n->parent->rchild=n->rchild;
	else
		root=n->rchild;
	n->rchild->parent=n->parent;
	n->parent=n->rchild;
	n->rchild=n->rchild->lchild;
	if(n->rchild!=NIL)
		n->rchild->parent=n;
	n->parent->lchild=n;
}

void RBTree::display(){
	if(!root)
		return;
	else
		show(root);
}

void RBTree::show(Node* p){
	cout<<p->value<<":";
	if(p->color==RED)
		cout<<"红";
	else
		cout<<"黑";
	cout<<"--左";
	if(p->lchild!=NIL)
		cout<<p->lchild->value<<"  ";
	cout<<"右";
	if(p->rchild!=NIL)
		cout<<p->rchild->value;
	cout<<endl;
	if(p->lchild!=NIL)
		show(p->lchild);
	if(p->rchild!=NIL)
		show(p->rchild);
}

void RBTree::destory(){
	if(!root)
		return;
	else
		desNode(root);
	delete NIL;
}

void RBTree::desNode(Node* p){
	if(p->lchild!=NIL)
		desNode(p->lchild);
	if(p->rchild!=NIL)
		desNode(p->rchild);
	cout<<"销毁"<<p->value<<"结点"<<endl;
	delete p;
}

//插入值为x的结点
void RBTree::insert(int x){
	if(!root)
		root=new Node(x,NIL,BLACK);
	else{
		Node* p=0;
		if(search(x,p)==0)
			return;
		else
			insertLoc(p,x);
	}
}

//查找元素函数
int RBTree::search(int x,Node* &p){
	//在以root为根的红黑树中查找关键字为x的元素,如果查找成功,返回0,p指向
	//查找到的元素的位置,否则返回1,p指向做比较的最后一个元素
	if(!root)
		return 1;
	p=root;
	while(p->value!=x){
		if(p->value>x && p->lchild!=NIL)
			p=p->lchild;
		else if(p->value<x && p->rchild!=NIL)
			p=p->rchild;
		else
			return 1;
	}
	return 0;
}

void RBTree::insertLoc(Node* p,int x){
	//以p结点为父节点插入关键字为x的结点
	Node *r=new Node(x,NIL);
	r->parent=p;
	if(p->value>x)
		p->lchild=r;
	else
		p->rchild=r;
	insertCase(r);
}

void RBTree::insertCase(Node* p){
	//插入一个结点后,如果不满足红黑树的条件,调整之
	if(p->parent==0)
		p->color=BLACK;
	else if(p->parent->color==BLACK)
		return;
	else if(p->uncle()->color==RED){
		p->parent->color=BLACK;
		p->uncle()->color=BLACK;
		p->grandParent()->color=RED;
		insertCase(p->grandParent());
	}
	else if(p==p->parent->rchild && p->parent==p->grandParent()->lchild){
		rotate_left(p->parent);
		p->color=BLACK;
		p->parent->color=RED;
		rotate_right(p->parent);
	}
	else if(p==p->parent->lchild && p->parent==p->grandParent()->rchild){
		rotate_right(p->parent);
		p->color=BLACK;
		p->parent->color=RED;
		rotate_left(p->parent);
	}
	else if(p==p->parent->lchild && p->parent==p->grandParent()->lchild){
		p->parent->color=BLACK;
		p->grandParent()->color=RED;
		rotate_right(p->grandParent());
	}
	else{
		p->parent->color=BLACK;
		p->grandParent()->color=RED;
		rotate_left(p->grandParent());
	}
}

Node* RBTree::getSmall(Node* p){
	Node* r=p->rchild;
	while(r->lchild!=NIL)
		r=r->lchild;
	return r;
}

void RBTree::swap(Node* ori,Node* re){
	//将re子树嫁接到ori原来的位置上
	if(ori->parent==0){
		//ori为根结点
		root=re;
		re->parent=0;
	}
	else{
		re->parent=ori->parent;
		if(ori==ori->parent->lchild)
			ori->parent->lchild=re;
		else
			ori->parent->rchild=re;
	}
}

void RBTree::deleteVal(int x){
	Node* p=0;
	if(search(x,p)==1)
		return;
	else
		deleteNode(p);
}

void RBTree::deleteNode(Node* n){
	Node *p=n,*r;
	if(p->lchild==NIL)
		r=p->rchild;
	else if(p->rchild==NIL)
		r=p->lchild;
	else{
		p=getSmall(p);
		r=p->rchild;
		n->value=p->value;
	}
	rb col=p->color;
	swap(p,r);
	delete p;
	deleteCase(r,col);
}

void RBTree::deleteCase(Node* n,rb col){
	if(col==RED)
		return;
	else{
		if(n->color==RED)
			n->color=BLACK;
		else if(n->parent!=0){
			Node* sb=n->sibling();
			if(sb->color==RED){
				n->parent->color=RED;
				sb->color=BLACK;
				if(n==n->parent->lchild)
					rotate_left(n->parent);
				else
					rotate_right(n->parent);
				deleteCase(n,BLACK);
			}
			else if(n->parent->color==BLACK && sb->lchild->color==BLACK && sb->rchild->color==BLACK){
				sb->color=RED;
				deleteCase(n->parent,BLACK);
			}
			else if(n->parent->color==RED && sb->lchild->color==BLACK && sb->rchild->color==BLACK){
				sb->color=RED;
				n->parent->color=BLACK;
			}
			else if(n==n->parent->lchild && sb->rchild->color==BLACK){
				sb->color=RED;
				sb->lchild->color=BLACK;
				rotate_right(sb);
				//旋转后,找出新的兄弟结点
				sb=n->sibling();
				sb->color=n->parent->color;
				n->parent->color=BLACK;
				sb->rchild->color=BLACK;
				rotate_left(n->parent);
			}
			else if(n==n->parent->rchild && sb->lchild->color==BLACK){
				sb->color=RED;
				sb->rchild->color=BLACK;
				rotate_left(sb);
				sb->color=n->parent->color;
				n->parent->color=BLACK;
				sb->lchild->color=BLACK;
				rotate_right(n->parent);
			}
			else{
				sb->color==n->parent->color;
				n->parent->color=BLACK;
				if(n==n->parent->lchild){
					sb->rchild->color=BLACK;
					rotate_left(n->parent);
				}
				else{
					sb->lchild->color=BLACK;
					rotate_right(n->parent);
				}
			}
		}
		else
			;
	}
	if(root==NIL)
		root=0;
}


#include <iostream>
#include "RBTree.h"

int main(void)
{
	RBTree tree;
	tree.insert(5);
	int arry[8]={4,6,5,7,2,9,3,8,};
	for(int i=0;i<8;++i)
		tree.insert(arry[i]);
	//tree.display();
	std::cout<<std::endl<<std::endl;
	for(int i=0;i<8;++i)
		tree.deleteVal(arry[i]);
	std::cout<<std::endl;
	tree.display();
	for(int i=0;i<8;++i)
		tree.insert(arry[i]);
	tree.display();
	for(int i=0;i<8;++i)
		tree.deleteVal(arry[i]);
	std::cout<<std::endl;
	tree.display();
	int a[20]={12,4,6,1,2,8,7,6,3,4,7,13,10,14,16,15,6,4,5,9};
	for(int i=0;i<20;++i)
		tree.insert(a[i]);
	tree.deleteVal(6);
	tree.display();
	system("pause");
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值