一个单纯的红黑树

本文深入解析了红黑树中fixup函数的工作原理及其三种不同的情况,详细阐述了左旋、右旋操作在不同场景下的应用,帮助读者更好地理解红黑树的内部机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <stdio.h>
#define RED 1
#define BLACK 2

class Node
{
public:
	static Node* Nil;
	Node* left;
	Node* right;
	Node* p;
	int data;
	int color;
	Node(int da,int col=RED):data(da),color(col)
	{
		this->left=Nil;
		this->right=Nil;
		this->p=Nil;
	}
	Node():color(BLACK),data(0)
	{}
};
class Tree
{
public:
	Node* root;
	Tree():root(0)
	{}
};
void rotate_left(Node* n)
{
	auto temp=n->right->left;
	n->right->left=n;
	n->right->p=n->p;
	if(n==n->p->left) n->p->left=n->right;
	else n->p->right=n->right;
	n->p=n->right;
	n->right=temp;
}
void rotate_right(Node* n)
{
	auto temp=n->left->right;
	n->left->right=n;
	if(n==n->p->left) n->p->left=n->left;
	else n->p->right=n->left;
	n->left->p=n->p;
	n->p=n->right;
	n->left=temp;
}
void fixup(Tree* tree,Node* node)
{
	while(node->p->color==RED)
	{
		auto g=node->p->p;
		if(node->p==g->left)
		{
			auto u=g->right;
			if(u->color==RED)
			{
				u->color=BLACK;
				node->p->color=BLACK;
				g->color=RED;
				node=g;
			}else
			{
				if(node==node->p->right)
					rotate_left(node->p);
				g->color=RED;
				node->p->color=BLACK;
				rotate_right(g);
			}
		}else
		{
			auto u=g->left;
			if(u->color==RED)
			{
				u->color=BLACK;
				node->p->color=BLACK;
				g->color=RED;
				node=g;
			}else
			{
				if(node==node->p->left)
					rotate_right(node->p);
				g->color=RED;
				node->p->color=BLACK;
				rotate_left(g);
			}
		}
	}
	while(tree->root->p!=Node::Nil) tree->root=tree->root->p;
	tree->root->color=BLACK;
}
void insert(Tree* tree,Node* root,Node* node)
{
	if(tree->root==NULL) tree->root=node;
	else
	{
		if(root->data < node->data)
		{
			if(root->right!=Node::Nil) insert(tree,root->right,node);
			else
			{
				root->right=node;
				node->p=root;
			}
		}else
		{
			if(root->left!=Node::Nil)  insert(tree,root->left,node);
			else
			{
				root->left=node;
				node->p=root;
			}
		}
	}
	fixup(tree,node);
}

void print_tree(Node* node)
{
	if(node==Node::Nil) return;
	putchar('(');
	print_tree(node->left);
	putchar(')');
	printf("%d",node->data);
	putchar('(');
	print_tree(node->right);
	putchar(')');
}
Node* Node::Nil=new Node();
int main()
{
	Node::Nil->left=Node::Nil;
	Node::Nil->right=Node::Nil;
	Node::Nil->p=Node::Nil;
	Tree* tree=new Tree();
	int array[]={1,2,3,4,5,6,7,8};
	for(int i=0;i<sizeof(array)/sizeof(int);++i) insert(tree,tree->root,new Node(array[i],RED));	
	print_tree(tree->root);
	return 0;

}




相信大家最难理解的部分就是fixup的三种case,就是为什么在这里左旋,又为什么在这里右旋,这里推荐大家看一下introduction algorithms里对RB-TREE的描述。花了3页详细介绍了RB-TREE的每个步骤。



转载于:https://my.oschina.net/000quanwei/blog/593862

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值