红黑树(插入,删除)C语言实现

笔者近来学习了一下红黑树,写出了初步代码。分享出来,同时这个代码并不保证没有bug,所以摆出来希望经过一番磨练。

#define _CRT_SECURE_NO_DEPRECATE

#include<stdio.h>
#include<stdlib.h>

// 定义颜色
typedef enum ColorType {RED,BLACK} COLOR;

#define datatype int 

typedef struct RBtree
{
	COLOR color;
	datatype data;
	struct RBtree *parent;
	struct RBtree *lchild, *rchild;

}RBtree;

// 包含一棵树的root指针和nil尾指针
typedef struct rbtree_rootandnil
{
	RBtree *root;
	RBtree *nil;
}TreeRN;


/*------函数声明------*/
TreeRN *initRBTree();
TreeRN *insertRBtreeFixup(TreeRN *T, RBtree *r);
TreeRN *insertRNtree(TreeRN *T, datatype i);
TreeRN *rightRotate(TreeRN *T, RBtree *r);
TreeRN *leftRotate(TreeRN *T, RBtree *r);
TreeRN *RBtransplant(TreeRN *T, RBtree *original, RBtree *replace);
TreeRN *RBtreeDeleteFix(TreeRN *T, RBtree *x);
TreeRN *RBtreeDelete(TreeRN *T, RBtree *r);
/*--------------------*/

/**********************
函数用途:初始化一棵红黑树
返回值  :树T
**********************/
TreeRN *initRBTree()
{
	TreeRN *T = (TreeRN *)malloc(sizeof(TreeRN));

	T->nil = (RBtree *)malloc(sizeof(RBtree));
	T->nil->color = BLACK;
	T->nil->parent = NULL;
	T->nil->rchild = T->nil->lchild = NULL;

	T->root = T->nil;
	return T;
}

/**********************
函数用途:以某一结点进行左旋
返回值  :树T
**********************/
TreeRN *leftRotate(TreeRN *T, RBtree *r)
{
	RBtree *y = r->rchild;
	r->rchild = y->lchild;
	if (y->lchild != T->nil)
		y->lchild->parent = r;
	y->parent = r->parent;
	if (r->parent == T->nil)
		T->root = y;
	else if (r == r->parent->lchild)
		r->parent->lchild = y;
	else r->parent->rchild = y;
	y->lchild = r;
	r->parent = y;

	return T;
}
// warning
/*左旋假设 r右孩子不是T->nil,根节点父节点为nil*/

/**********************
函数用途:以某一结点进行右旋
返回值  :树T
**********************/
TreeRN *rightRotate(TreeRN *T, RBtree *r)
{
	RBtree *y = r->lchild;
	r->lchild = y->rchild;
	if (y->rchild != T->nil)
		y->rchild->parent = r;
	y->parent = r->parent;
	if (r->parent == T->nil)
		T->root = y;
	else if (r == r->parent->lchild)
		r->parent->lchild = y;
	else r->parent->rchild = y;
	y->rchild = r;
	r->parent = y;
	return T;
}
/**********************
函数用途:插入操作,像二叉搜索树类似的插入
返回值  :树T
**********************/
TreeRN *insertRNtree(TreeRN *T, datatype i)
{
	RBtree *y = T->root;
	RBtree *x = T->nil;
	while (y != T->nil)
	{
		x = y;
		if (i < y->data)
			y = y->lchild;
		else y = y->rchild;
	}
	y = (RBtree *)malloc(sizeof(RBtree));
	y->data = i;
	y->parent = x;
	if (T->root == T->nil)
	{
		T->root = y;
	}
	else if (i < x->data)
		x->lchild = y;
	else x->rchild = y;
	y->lchild = T->nil;
	y->rchild = T->nil;
	y->color = RED;
	T = insertRBtreeFixup(T, y);

	return T;
}


/**********************
函数用途:插入函数校准,使符合红黑树性质
返回值  :树T
**********************/
TreeRN *insertRBtreeFixup(TreeRN *T, RBtree *r)
{
	RBtree *y;
	while (r->parent->color == RED)
	{
		if (r->parent == r->parent->parent->lchild)
		{
			y = r->parent->parent->rchild;
			if (y->color == RED)
			{
				r->parent->color = BLACK;
				y->color = BLACK;
				r->parent->parent->color = RED;
				r = r->parent->parent;
			}
			else
			{
				if (r == r->parent->rchild)
				{
					r = r->parent;
					T = leftRotate(T, r);
				}
				r->parent->color = BLACK;
				r->parent->parent->color = RED;
				T = rightRotate(T, r->parent->parent);
			}
		}
		else                                                     // r父节点是爷爷的右孩子
		{
			y = r->parent->parent->lchild;
			if (y->color == RED)
			{
				r->parent->color = BLACK;
				y->color = BLACK;
				r->parent->parent->color = RED;
				r = r->parent->parent;
			}
			else
			{
				if (r == r->parent->lchild)
				{
					r = r->parent;
					T = rightRotate(T, r);
				}
				r->parent->color = BLACK;
				r->parent->parent->color = RED;
				T = leftRotate(T, r->parent->parent);
			}
		}
	}
	T->root->color = BLACK;
	return T;
}

/**********************
函数用途:以某一结点替代另一节点
返回值  :树T
**********************/
TreeRN *RBtransplant(TreeRN *T, RBtree *original, RBtree *replace)
{
	if (original->parent == T->nil)
		T->root = replace;
	else if (original == original->parent->lchild)
		original->parent->lchild = replace;
	else original->parent->rchild = replace;
	if (replace != T->nil)
	{
		replace->parent = original->parent;
	}
	return T;
}

/**********************
函数用途:红黑树中结点删除操作
返回值  :树T
**********************/

TreeRN *RBtreeDelete(TreeRN *T, RBtree *r)
{
	RBtree *x, *y = r;
	COLOR reserveColor = y->color;
	if (y->lchild == T->nil)
	{
		x = r->rchild;
		T = RBtransplant(T, r, r->rchild);
		//x->parent = y;
	}
	else if (y->rchild == T->nil)
	{
		x = r->lchild;
		T = RBtransplant(T, r, r->lchild);
	}
	else
	{
		y = r->rchild;
		for (; y->lchild != T->nil; y = y->lchild);
		reserveColor = y->color;
		x = y->rchild;
		if (y->parent == r)
			x->parent = y;
		else
		{
			T = RBtransplant(T, y, y->rchild);
			y->rchild = r->rchild;
			y->rchild->parent = y;
		}
		T = RBtransplant(T, r, y);
		y->lchild = r->lchild;
		y->lchild->parent = y;
		y->color = r->color;
	}
	free(r);
	if (reserveColor == BLACK)
		T = RBtreeDeleteFix(T, x);
	return T;
}

/**********************
函数用途:删除校准,使其再度符合红黑树性质
返回值  :树T
**********************/
TreeRN *RBtreeDeleteFix(TreeRN *T, RBtree *x)
{
	RBtree *y;
	while (x != T->root&&x->color == BLACK)
	{
		if (x == x->parent->lchild)
		{
			y = x->parent->rchild;
			if (y->color == RED)
			{
				y->color = BLACK;
				x->parent->color = RED;
				T = leftRotate(T, x->parent);
				y = x->parent->rchild;
			}
			if (y->lchild->color == BLACK && y->rchild->color == BLACK)
			{
				y->color = RED;
				x = x->parent;
			}
			else
			{
				if (y->rchild->color == BLACK)
				{
					y->lchild->color = BLACK;
					y->color = RED;
					T = rightRotate(T, y);
					y = x->parent->rchild;
				}
				y->color = x->parent->color;
				x->parent->color = BLACK;
				y->rchild->color = BLACK;
				T = leftRotate(T, x->parent);
				x = T->root;
			}
		}
		else
		{
			y = x->parent->lchild;
			if (y->color == RED)
			{
				y->color = BLACK;
				x->parent->color = RED;
				T = rightRotate(T, x->parent);
				y = x->parent->lchild;
			}
			if (y->rchild->color == BLACK && y->lchild->color == BLACK)
			{
				y->color = RED;
				x = x->parent;
			}
			else
			{
				if (y->lchild->color == BLACK)
				{
					y->rchild->color = BLACK;
					y->color = RED;
					T = leftRotate(T, y);
					y = x->parent->lchild;
				}
				y->color = x->parent->color;
				x->parent->color = BLACK;
				y->lchild->color = BLACK;
				T = rightRotate(T, x->parent);
				x = T->root;
			}
		}
	}

	x->color = BLACK;
	return T;
}

插入情况

删除情况

猜你喜欢

转载自blog.csdn.net/domoNaruto/article/details/82770381