红黑树(RBTree)

红黑树具有以下特性:

节点颜色: 每个节点要么是红色,要么是黑色。
根节点: 根节点是黑色的。
叶子节点(NIL节点): 叶子节点是黑色的,也被称为NIL节点。它们不存储任何数据,只是作为树结构的辅助。所有指向NIL节点的指针都被认为是黑色的。
颜色限制: 不能有两个相连的红色节点,即红色节点不能相邻,每个红色节点的子节点都是黑色的。
黑高度: 从任意节点出发,到达其每个叶子节点的路径上的黑色节点数量必须相同,这被称为黑高度。这个性质保证了树的平衡。
 

#include<iostream>
#include<stdio.h>
#include<assert.h>

typedef enum{RED = 0,BLACK = 1} ColorType;
typedef int KeyType;
typedef struct RBNode
{
	RBNode* leftchild;
	RBNode* rightchild;
	RBNode* parent;
	ColorType color;
	KeyType key;
}RBNode;
typedef struct
{
	RBNode* root;
	RBNode* Nil;
	int cursize;
}RBTree;

RBNode* BuyNode(RBNode*parg,ColorType carg)
{
	RBNode* ptr = (RBNode*)calloc(1, sizeof(RBNode));
	if (ptr == nullptr) exit(EXIT_FAILURE);
	ptr->color = carg;
	ptr->parent = parg;
	return ptr;
}
void FreeNode(RBNode* ptr)
{
	free(ptr);
}
void InitRBTree(RBTree* ptree)
{
	assert(ptree != nullptr);
	ptree->Nil = BuyNode(nullptr, BLACK);
	ptree->root = ptree->Nil;
	ptree->cursize = 0;
}
RBNode* FindValue(RBTree* ptree, const KeyType kx)
{
	assert(ptree != nullptr);
	RBNode* p = ptree->root;
	while (p != ptree->Nil && p->key != kx)
	{
		p = kx < p->key ? p->leftchild : p->rightchild;
	}
	return p;
}
RBNode* First(RBTree *ptree , RBNode* ptr)
{
	assert(ptree != nullptr && ptr != nullptr);
	while (ptr != ptree->Nil && ptr->leftchild != ptree->Nil)
	{
		ptr = ptr->leftchild;
	}
	return ptr;
}
RBNode* Next(RBTree* ptree, RBNode* ptr)
{
	if (ptr == ptree->Nil || ptr == nullptr) return ptree->Nil;
	if (ptr->rightchild != ptree->Nil)
	{
		return First(ptree, ptr->rightchild);
	}
	else
	{
		RBNode* pa = ptr->parent;
		while (pa != nullptr && pa->leftchild != ptr)
		{
			ptr = pa;
			pa = ptr->parent;
		}
		return pa;
	}
}
void NiceInOrder(RBTree* ptree)
{
	assert(ptree != nullptr);
	for (RBNode* ptr = First(ptree, ptree->root);!(ptr == nullptr || ptr == ptree->Nil); ptr = Next(ptree, ptr))
	{
		printf("Color: %s  Key: %3d\n",((ptr->color==RED)?"红色":"黑色"), ptr->key); 
	}
	printf("\n");
}
RBNode* RotateLeft(RBTree* ptree, RBNode* ptr)
{
	assert(ptree != nullptr && ptr != nullptr);
	RBNode* newroot = ptr->rightchild;//1
	newroot->parent = ptr->parent;
	ptr->rightchild = newroot->leftchild;//2
	if (newroot->leftchild != ptree->Nil)//是否有左孩子
	{
		newroot->leftchild->parent = ptr;
	}
	newroot->leftchild = ptr;//3
	RBNode* pa = ptr->parent;
	if (pa == nullptr)//ptr是否为根
	{
		ptree->root = newroot;
	}
	else
	{
		if (pa->leftchild == ptr)
		{
			pa->leftchild = newroot;
		}
		else
		{
			pa->rightchild = newroot;
		}
	}
	ptr->parent = newroot;
	return newroot;
}
RBNode* RotateRight(RBTree* ptree, RBNode* ptr)
{
	assert(ptree != nullptr && ptr != nullptr);
	RBNode* newroot = ptr->leftchild;//1
	newroot->parent = ptr->parent;
	ptr->leftchild = newroot->rightchild;//2
	if (newroot->rightchild != ptree->Nil)//无右孩子
	{
		newroot->rightchild->parent = ptr;
	}
	newroot->rightchild = ptr;//3
	RBNode* pa = ptr->parent;
	if (pa == nullptr)//ptr是否为根
	{
		ptree->root = newroot;
	}
	else
	{
		if (pa->leftchild == ptr)
		{
			pa->leftchild = newroot;
		}
		else
		{
			pa->rightchild = newroot;
		}
	}
	ptr->parent = newroot;
	return newroot;
}
void Insert(RBTree* ptree, RBNode* pa, const KeyType kx)
{
	RBNode* s = BuyNode(pa, RED);
	s->key = kx;
	s->leftchild = ptree->Nil;
	s->rightchild = ptree->Nil;
	if (pa == nullptr)//空树
	{
		ptree->root = s;
	}
	else
	{
		if (pa->key > s->key)
		{
			pa->leftchild = s;
		}
		else
		{
			pa->rightchild = s;
		}
	}
	RBNode* p = s;
	while (p != ptree->root && p->parent->color == RED)
	{
		if (p->parent == p->parent->parent->rightchild)//判断插入节点为右孩子
		{
			RBNode* left = p->parent->parent->leftchild;
			if (left->color == RED)//着色来调整
			{
				p->parent->color = BLACK;
				p->parent->parent->color = RED;
				left->color = BLACK;
				p = p->parent->parent;
			}
			else
			{
				if (p == p->parent->leftchild)//折线进行双旋
				{
					p = p->parent;
					RotateRight(ptree, p);
				}
				p->parent->color = BLACK;
				p->parent->parent->color = RED;
				RotateLeft(ptree, p->parent->parent);
			}
		}
		else
		{
			RBNode* right = p->parent->parent->rightchild;
			if (right->color == RED)//着色来调整
			{
				p->parent->color = BLACK;
				p->parent->parent->color = RED;
				right->color = BLACK;
				p = p->parent->parent;
			}
			else
			{
				if (p == p->parent->rightchild)//折线进行双旋
				{
					p = p->parent;
					RotateLeft(ptree, p);
				}
				p->parent->color = BLACK;
				p->parent->parent->color = RED;
				RotateRight(ptree, p->parent->parent);
			}
		}
	}
	ptree->root->color = BLACK;
}
bool Insert_Item(RBTree* ptree, const KeyType kx)
{
	assert(ptree != nullptr);
	RBNode* p = ptree->root;
	RBNode* pa = nullptr;
	while (p != ptree->Nil && p->key != kx)
	{
		pa = p;
		p = kx < p->key ? p->leftchild : p->rightchild;
	}
	if (p != ptree->Nil) return false;
	Insert(ptree, pa, kx);
	ptree->cursize += 1;
	return true;
}


int main()
{
	KeyType ar[] = { 16,3,7,11,9,26,18,14,15,45,34,50 };
	int len = sizeof(ar) / sizeof(ar[0]);
	RBTree tree;
	InitRBTree(&tree);
	for (int i = 0; i < len; ++i)
	{
		Insert_Item(&tree, ar[i]);
	}
	NiceInOrder(&tree);

	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值