rb树-红黑树

1.定义

红黑树是一种二叉查找树,每一个节点增加一个存储位表示节点的颜色,可以是黑或红。通过对任何一条从根到叶子的路径上的各个节点着色方式的限制,红黑树确保没有一条路径会比其他路径长两倍,是一种弱平衡二叉树,相对于要求严格的AVL树来说,他的旋转次数少,对于搜索,插入,删除操作较多的情况下,通常使用红黑树。

2.性质:

每个节点非黑即红

根节点是黑的

每个叶节点(树尾端)都是黑的

如果一个节点是红色的,则他的字节的必须是黑的

对于任意节点而言,其叶子结点树NULL指针的每条路径都包含相同数目的黑节点

在o(log n)时间内做查找,插入,删除

从根到叶子的最长可能路径不多于最短的可能路径的两倍长

3.实际使用

STL中map和set的底层,
epoll的文件系统中,
伙伴关系中内存的平衡,
linux中进程的调度用的是红黑树

epoll的底层是用红黑树和双向链表实现的,epoll_create()系统调用在内核中创建一个eventpoll类型的句柄,包括rbtree的根节点和双向链表的头结点,然后通过epoll_ctl()系统调用,向epoll对象的红黑树结构中添加,删除修改,返回0标识成功,返回-1表示失败。最后通过epoll_wait()系统调用判断双向链表是否为空,空则阻塞。文件描述符状态改变,fd上的毁掉函数被调用,该函数将fd加入双向链表,此时epoll_wait函数被唤醒,返回就绪好的实践。

4.代码实现

#include<iostream>
using namespace std;

typedef enum {RED=0,BLACK=1} ColorType;

typedef int KeyType;
typedef struct rb_node
{
	rb_node* leftchild;
	rb_node* parent;
	rb_node* rightchild;
	ColorType color;
	KeyType key;
}rb_node,*RBTree;

rb_node* BuyNode();
static rb_node* Nil = BuyNode();
rb_node* BuyNode()
{
	rb_node* s = (rb_node*)malloc(sizeof(rb_node));
	if (nullptr == s)	exit(1);
	memset(s, 0, sizeof(rb_node));
	s->color = RED;
	s->leftchild = Nil;
	s->rightchild = Nil;
	return s;
}

rb_node* Buynode(KeyType kx)
{
	rb_node* s = (rb_node*)malloc(sizeof(rb_node));
	if (nullptr == s)	exit(1);
	memset(s, 0, sizeof(rb_node));
	s->key = kx;
	
	return s;
}
//左单旋
//1.2.3步,是旋转时 的思路,(a,b,c)是改写parent指针的指向
void RotateLeft(rb_node*& tree, rb_node* ptr)
{
	rb_node* newroot = ptr->rightchild;//1
	newroot->parent = ptr->parent;//a
	ptr->rightchild = newroot->leftchild;//2
	if (newroot->leftchild != nullptr)//排除12,23,34,这种
	{
		newroot->leftchild->parent = ptr;//b
	}
	newroot->leftchild = ptr;//3
	//是根
	if (ptr == tree)	tree = newroot;
	else
	{
		if (ptr->parent->leftchild == ptr)
		{
			ptr->parent->leftchild = newroot;
		}
		else
		{
			ptr->parent->rightchild = newroot;
		}
	}
	ptr->parent = newroot;//c
}
//右单旋转
void RotateRight(rb_node*& tree,rb_node* ptr)
{
	rb_node* newroot = ptr->leftchild;
	newroot->parent= ptr->parent ;
	ptr->leftchild = newroot->rightchild;
	if (newroot->rightchild != nullptr)
	{
		newroot->rightchild->parent = ptr;
	}
	newroot->rightchild = ptr;
	if (ptr == tree)	tree = newroot;
	else
	{
		if (ptr->parent->leftchild == ptr)
		{
			ptr->parent->leftchild = newroot;
		}
		if (ptr->parent->rightchild == ptr)
		{
			ptr->parent->rightchild = newroot;
		}
	}
	ptr->parent = newroot;
}
void PassRBTree(rb_node*& tree, rb_node* p)
{
	rb_node* _X = nullptr;
	for (; p != tree && p->parent->color==RED;)
	{
		if (p->parent->parent->rightchild == p->parent)
		{
			if (p->parent->parent->rightchild == p->parent)
			{
				_X = p->parent->parent->leftchild;
				if (_X->color == RED)
				{
					_X->color = BLACK;
					p->parent->color = BLACK;
					p->parent->parent->color = RED;
					p = p->parent->parent;
				}
				else
				{
					if (p->parent->leftchild == p)
					{
						p = p->parent;
						RotateRight(tree, p);
					}
					p->parent->color = BLACK;
					p->parent->parent-> color = RED;
					RotateLeft(tree, p->parent->parent);
				}
			}
		}
	}
	
}
rb_node* MakeRoot(KeyType kx)
{
	rb_node* root = BuyNode();
	root->color = BLACK;
	root->key = kx;
	return root;
}
bool Insert(rb_node*& root, KeyType key)
{
	if (root== nullptr)
	{
		root= MakeRoot(key);
		return true;
	}
	rb_node* pa = nullptr;
	rb_node* p = root;
	while (p != nullptr && p->key !=key)
	{
		pa = p;
		p = key < p->key ? p->leftchild : p->rightchild;
	}
	if (p != nullptr && p->key == key)	return false;
	p = Buynode(key);
	p->parent = pa;
	if (key < pa->key)
	{
		pa->leftchild = p;
	}
	else
	{
		pa->rightchild = p;
	}
	PassRBTree(root, p);
	return true;
	return true;
}


 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值