红黑树C代码实现

#include "rbt.h"


bool Init_RBT(rb_root *T)
{
	if(T == NULL)
	{
		T = (rb_root*)malloc(sizeof(rb_root));
		if( T == NULL)
			return false;
		T->root = NULL;
		return true;
	}

	return false;
}

NodeStatus RbtLeftRotate(Node *x, rb_root *T)
{
	if( T == NULL)
		return False;
	//parent
	if(x->rchild->parent = x->parent)
	{
		if(x->parent->rchild == x)
			x->parent->rchild = x->rchild;
		else
			x->parent->lchild = x->rchild;
	}
	else
		T->root = x->rchild;
	x->parent = x->rchild;

	//rchild
	if(x->rchild->lchild == NULL)
		x->rchild = NULL;
	else
	{
		x->rchild->lchild->parent = x;
		x->rchild = x->rchild->lchild;
	}
	x->parent->lchild = x;

	return OP_SUCCESS;
}

NodeStatus RbtRightRotate(Node *x, rb_root *T)
{
	if( T == NULL)
		return False;
	//parent
	if(x->lchild->parent = x->parent)
	{
		if(x->parent->rchild == x)
			x->parent->rchild = x->lchild;
		else
			x->parent->lchild = x->lchild;
	}
	else
		T->root = x->lchild;
	x->parent = x->lchild;

	//rchild
	if(x->lchild->rchild == NULL)
		x->lchild = NULL;
	else
	{
		x->lchild->rchild->parent = x;
		x->lchild = x->lchild->rchild;
	}
	x->parent->rchild = x;

	return OP_SUCCESS;
}


NodeStatus find_next(Node *T, Node *Next)
{
	if(T == NULL)
		return False;

	if(NULL == T->parent && NULL == T->rchild && NULL == T->lchild)
		return RootNode;

	if(NULL == T->rchild && NULL == T->lchild)
		return NilNode;
	else if(NULL == T->rchild)
		return NoRchild;

	Next = T->rchild;
	while(NULL != Next->lchild)
		Next = Next->lchild;

	return OP_SUCCESS;

}

NodeStatus find_prev(Node *T, Node *prev)
{
	if(T == NULL)
		return False;

	if(NULL == T->parent && NULL == T->rchild && NULL == T->lchild)
		return RootNode;

	if(NULL == T->rchild && NULL == T->lchild)
		return NilNode;
	else if(NULL == T->lchild)
		return NoLchild;

	prev = T->lchild;
	while(NULL != prev->rchild)
		prev = prev->rchild;

	return OP_SUCCESS;

}


NodeStatus InsertNode(int key_value, rb_root *T)
{
	if(T == NULL)
		Init_RBT(T);

	Node *x = (Node*)malloc(sizeof(Node));
	x->lchild = NULL;
	x->rchild = NULL;
	x->parent = NULL;
	x->color = red;
	x->key = key_value;

	if(T->root == NULL)
	{
		T->root = x;
		x->color = black; //root node must be black
		return OP_SUCCESS;
	}

	Node *next = T->root;
	while(1)
	{
		if(key_value == next->key)
		{//same value Node ignore or add Node->KeyTimes + 1
			free(x);
			return SameKey;
		}
		if(key_value < next->key)
		{
			if(NULL == next->lchild)
			{//nil set
				next->lchild = x;
				x->parent = next;
				Insert_col_fix(x, T);
				return OP_SUCCESS;
			}
			next = next->lchild;
		}

		if(key_value > next->key)
		{
			if(NULL == next->rchild)
			{
				next->rchild = x;
				x->parent = next;
				Insert_col_fix(x, T);
				return OP_SUCCESS;
			}
			next = next->rchild;
		}

	}

	return False;

}


NodeStatus Insert_col_fix(Node *node, rb_root *root)
{
	if(NULL == root || NULL == node)
		return False;

	/* modify from the linux-kernel 2.6.9 /lib/rntree.c--rb_insert_color function */
	Node *parent, *gparent;
	while ((parent = node->parent) && parent->color == red)
	{
		gparent = parent->parent;

		if (parent == gparent->lchild)
		{
			{
				register Node *uncle = gparent->rchild;
				if (uncle && uncle->color == red) 
				{//node red ,parent lchild and red ,uncle rchild and red
					uncle->color = black;
					parent->color = black;
					gparent->color = red;
					node = gparent; //set node to gparent
					continue;
				}
			}

			if (parent->rchild == node)
			{//node red and rchild, parent red and lchild
				register Node *tmp;
				RbtLeftRotate(parent, root); //left_rotate the parent
				tmp = parent;
				parent = node;
				node = tmp;
			}

			parent->color = black;
			gparent->color = red;
			RbtRightRotate(gparent, root);
		} else {
			{
				register Node *uncle = gparent->lchild;
				if (uncle && uncle->color == red)
				{//parent red and rchild,uncle red and lchild,node red
					uncle->color = black;
					parent->color = black;
					gparent->color = red;
					node = gparent;
					continue;
				}
			}

			if (parent->lchild == node)
			{//node red and lchild,parent red and rchild
				register Node *tmp;
				RbtRightRotate(parent, root);
				tmp = parent;
				parent = node;
				node = tmp;
			}

			parent->color = black;
			gparent->color = red;
			RbtLeftRotate(gparent, root);
		}
	}

	root->root->color = black;
	return OP_SUCCESS;
}

NodeStatus find_key_node(Node *find, int key, rb_root *T)
{
	if(NULL == T)
		return False;

	if(NULL == T->root)
		return EmptyTree;

	find = T->root;
	while (key != find->key)
	{
		if(key > find->key)
		{
			if(find->rchild == NULL)
				return NoRchild;
			find = find->rchild;
		}
		else
		{
			if(find->lchild == NULL)
				return NoLchild;
			find = find->lchild;
		}
	}

	return OP_SUCCESS;
}



NodeStatus del_node(int key, rb_root *T)
{
	if(NULL == T)
		return False;

	Node *find = NULL;
	NodeStatus Ret = find_key_node(find, key, T);
	if(OP_SUCCESS != Ret)
		return False;

	Node *NextNode = NULL, *child, *parent;
	NodeColor color = def;

	if(find->rchild && find->lchild)
	{
		if(find_next(find, NextNode))
			return False;

		child = NextNode->rchild;
		parent = NextNode->parent;
		color = NextNode->color;

		if(child)
			child->parent = parent;
		if(parent->lchild == NextNode)
			parent->lchild = child;
		else
			parent->rchild = child;
		find->key = NextNode->key;

		free(NextNode);
	}
	else
	{
		if(!find->lchild)
			child = find->rchild;
		else if(NoRchild == Ret)
			child = find->lchild;
		
		parent = find->parent;
		color = find->color;

		if(child)
			child->parent = parent;
		if(parent)
		{
			if(parent->lchild == find)
				parent->lchild = child;
			else
				parent->rchild = child;
		}
		else
			T->root = child;

		free(find);

	}

	if(black == color)
		return del_col_fix(child, parent, T);
	
	return OP_SUCCESS;
}

NodeStatus del_col_fix(Node *node, Node *parent, rb_root *T)
{
	Node *brother;

	while((!node || node->rchild == black) && node != T->root)
	{//node is nilnode or node rchild is black ,node is not root
		if (parent->lchild == node)
		{
			brother = parent->rchild;

			if (brother->color == red)
			{//brother is red
				brother->color = black;
				parent->color = red;
				RbtLeftRotate(parent, T);
				brother = parent->rchild; //update brother
			}

			if ((!brother->rchild || brother->rchild->color == black)\
					&& (!brother->lchild || brother->lchild->color == black))
			{//brother's rchild and lchild are nil or black,brother is black
				brother->color = red;
				node = parent; //if parent is red ,jump loop,set node to black
				parent = node->parent;
			}
			else
			{
				if (!brother->rchild || brother->rchild->color == black)
				{//brother(black) rchild is black ,lchild is red
					brother->color = red;
					brother->lchild->color = black;
					RbtRightRotate(brother, T);
					brother = parent->rchild;
				}
				//brother(black) rchild is red
				brother->color = parent->color;
				parent->color = black;
				brother->rchild->color = black;
				RbtLeftRotate(parent, T);
				break;
			}

		}
		else
		{
			brother = parent->lchild;

			if (brother->color == red)
			{
				brother->color = black;
				parent->color = red;
				RbtRightRotate(parent, T);
				brother = parent->lchild;
			}

			if((!brother->lchild || brother->lchild->color == black)\
					&& (!brother->rchild || brother->rchild->color == black))
			{
				brother->color = red;
				node = parent;
				parent = node->parent;
			}
			else
			{
				if(!brother->lchild || brother->lchild->color == black)
				{
					brother->color = red;
					brother->rchild->color = black;
					RbtLeftRotate(brother, T);
					brother = parent->lchild;
				}

				brother->color = parent->color;
				parent->color = black;
				brother->lchild->color = black;
				RbtRightRotate(parent, T);
				break;
			}
		}

		if(node->color == red)
			node->color = black;
	}


}


 

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


typedef enum{
	red,
	black,
	def
}NodeColor;

typedef struct RBTreeNode{
	NodeColor color;
	int key;
	struct RBTreeNode *rchild, *lchild, *parent;
}Node, *RBTree;

typedef struct T_root{
	RBTree root; 
}rb_root;

typedef enum {
	OP_SUCCESS = 0,
	RootNode,
	NilNode,
	NoRchild,
	NoLchild,
	SameKey,
	EmptyTree,
	False	
}NodeStatus;


NodeStatus Insert_col_fix(Node *node, rb_root *root);
NodeStatus del_col_fix(Node *node, Node *parent, rb_root *T);

 

 

 

红黑树的特性:

1.节点是红色或黑色。

2.根节点是黑色。

3.每个叶子节点都是黑色的空节点(NIL节点)。

4 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)

5.从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

 

 

插入时总是要考虑它的叔叔,删除时总要考虑它的兄弟。而且插入时维护的主要是颜色(性质4),而删除时维护的主要是黑色结点数量(性质5)

 

详情参考

https://blog.csdn.net/weewqrer/article/details/51866488

和Linux源码/lib/rbtree.c

 

 

 

 

 

 

©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值