红黑树(c实现)

学习红黑树原理,网络上有很多文章。学习红黑树的具体实现,个人推荐去看JDK中的TreeMap源码。因为该源码很简洁,并且很容易改为其它语言的实现,最重要的是该份实现得到世人的认可,可以保证是没问题的代码。

下面是我根据其实现,使用c语言改写的红黑树实现,目前只有红黑树的插入实现。

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

enum COLOR {
	red,
	black
};

typedef struct Node {
	struct Node *left,*right,*parent;
	int value;
	int color;
} Node , *Tree;

Node* p(Node* x)
{
	return x->parent;
}
Node* u(Node* x)
{
	if(p(p(x))->left == p(x))
	{
		return p(p(x))->right;
	} else {
		return p(p(x))->left;
	}
}

int color(Node* x)
{
	if(x != NULL)
	{
		return x->color;
	} else {
		return black;
	}
}
void ll(Tree &T,Node *x)
{
	if(x->right != NULL)
	{
		Node *y = x->right;
		x->right = y->left;

		if(y->left != NULL)
		{
			y->left->parent = x;
		}

		y->parent = x->parent;

		if(x->parent != NULL)
		{
			if(p(x)->left == x)
			{
				p(x)->left = y;
			} else {
				p(x)->right = y;
			}
		} else {
			T = y;
		}
		y->left = x;
		x->parent = y;
	}
}

void rr(Tree &T,Node *x)
{
	if(x->left != NULL)
	{
		Node *y = x->left;
		x->left = y->right;
		if(y->right != NULL)
		{
			y->parent = x;
		}
		y->parent = x->parent;
		if(p(x) != NULL)
		{
			if(p(x)->left == x)
			{
				p(x)->left = y;
			} else {
				p(x)->right = y;
			}
		} else {
			T = y;
		}
		y->right = x;
		x->parent = y;
	}	
}

void fixupafterinsert(Tree &t,Node *x)
{
	x->color = red;
	while( x != NULL && x != t && p(x)->color == red )
	{
		if(p(p(x))->left == p(x))
		{
			//在左侧
			if(color(u(x)) == red)
			{
				//叔的颜色是红色
				p(x)->color = black;
				u(x)->color = black;
				p(p(x))->color = red;
				x = p(p(x));//进入下次循环,进行调整
			} else {
				//叔的颜色是黑色,或者空
				//判断在左还是右
				if(p(x)->right == x)//因为最开始考虑的是左树,所以此处要先考虑右子
				{
					x = p(x);
					ll(t,x);
				}
				//然后着色,父黑色,祖父是红色
				p(x)->color = black;
				p(p(x))->color = red;
				rr(t,p(p(x)));
				//此时黑色的父是根,x是左子,祖是右子
				//调整完毕
			}
		} else {
			//在右子树上
			if(color(u(x)) == red)
			{
				p(x)->color = black;
				u(x)->color = black;
				p(p(x))->color = red;
				x = p(p(x));
			} else {
				//考虑叔是黑色,或空
				if(p(x)->left == x)
				{
					//右旋
					x = p(x);
					rr(t,x);
				}
				//着色,然后左旋
				p(x)->color = black;
				p(p(x))->color = red;
				ll(t,p(p(x)));
			}
		}
	}
	//此处处理根
	t->color = black;
}

void print(Node *x)
{
	if(x != NULL)
	{
		print(x->left);
		printf("%d ",x->value);
		print(x->right);
	}
}
void insert(Tree &t ,int n)
{
	if(t==NULL)
	{
		t = (Node*)malloc(sizeof(Node));
		t->left = NULL;
		t->right = NULL;
		t->value = n;
		t->color = black;
	} else {
		Node* x = t;
		Node* p = NULL;
		while(x != NULL)
		{
			if(n < x->value)
			{
				p = x;
				x = x->left;
			} else {
				p = x;
				x = x->right;
			}
		}
		x = (Node*)malloc(sizeof(Node));
		x->left = NULL;
		x->right = NULL;
		x->value = n;
		x->color = red;
		x->parent = p;
		if(n < p->value)
		{
			p->left = x;
		} else {
			p->right = x;
		}
		fixupafterinsert(t,x);
	}
}
int main(void)
{
	Node* root;
	insert(root,30);
	insert(root,50);
	insert(root,60);
	insert(root,60);
	insert(root,70);
	insert(root,10);
	print(root);
	return 0;
}

该源码确定能够运行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值