随处可见的红黑树(数据结构与算法)

随处可见的红黑树

红黑树性质

  1. 每个节点不是红色就是黑色的
    2. 根节点是黑色
    3. 每个叶子节点是黑色
    2 根和叶子节点都是黑色的
  2. 如果一个结点是红色的,则他的两个根节点都是黑色的
    (没有连续的两个红色父子结点)
  3. 对于每个节点,从该节点到其子孙结点的所有路径上都包含相同数目的黑节点
    (对于每个节点,黑高都相同

黑高 用来判断 是否是红黑树

红黑树的应用场景

  • Linux进程调度 CFS
  • Nginx Timer 事件管理
  • Epoll 事件块的管理

红黑树的数据证明与推导

WHY

  • 1 红黑树为什么要进行左旋 右旋 变色呢?
    在插入,删除操作的时候,会破坏红黑树的自平衡,为了实现红黑树的自平衡
  • 2
  • 3
  • 4

手撕红黑树的左旋与右旋

在这里插入图片描述
思路:左旋涉及到 x的父节点 x y b 共四个结点的交互,具体来说:

  • x的右节点指向b
  • b的父节点指向x
  • y的父节点指向x的父节点
  • x的父节点的左(或右)结点指向y
  • x的父节点指向y
  • y的左节点指向x

左旋

void retree_left_rotate(rbtree *T, rebtree_node *x)
{
	rbtree_node *y = x->right;
	
	x->right = y->left;
	if (y->left != T->nil){
		y->left->parent = x;
	}
	
	y->parent = x->parent;
	if (x->parent == T->nil) {
		T->root = y;
	} else if (x == x->parent->left) {
		x->parent->left = y;
	} else {
		x->parent->right = y;
	}
	x->parent = y;
	y->left = x;
}

右旋

void rbtree_right_rotate(rbtree *T, rbtree_node *y) {

	rbtree_node *x = y->left;

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

	x->parent = y->parent;
	if (y->parent == T->nil) {
		T->root = x;
	} else if (y == y->parent->right) {
		y->parent->right = x;
	} else {
		y->parent->left = x;
	}

	x->right = y;
	y->parent = x;
}

红黑树插入的实现与添加三种情况的证明

  • 查找插入的位置
    插入结点后,第一个问题,设置当前结点颜色为红色?黑色?
    红色,因为如果为黑色,则一定破坏左右结点黑高一致的原则,如果为红色,则可能破坏父子结点为
    红色的原则,所以要进行下一步插入后的自平衡操作
  • 插入后自平衡
    1.无需进行 变色,左旋,右旋
    2.变色 :若 插入结点的父节点为红色(可以推到父节点一定为黑色),叔父结点为红色,需要变色—>父节点,叔父结点 与 祖父结点 颜色变化【这也是唯一一种会增加红黑树黑色结点层数(因为默认插入的结点颜色是红色,左旋,右旋也不会改变黑色结点层数)的插入情景】
    3.左旋,右旋:若 插入结点的父结点为红色,叔父结点不存在(为黑色(叶子结点)),此时因为左右结点层数不一致,这个时候应该想到左旋,右旋操作 + 变色 (TODO)

红黑树的线程安全做法

  • 对每个正在操作的结点加锁

分析红黑树工程实用的特点

红黑树等数据结构的插入删除

在线模拟
参考文章1
AVL 和 红黑树

思考

  • 1 黑结点可以同时包含一个红子结点和一个黑子结点吗?
    可以,如下所示
    在这里插入图片描述

  • 2

  • 3

案例分析

案例一、服务器端高并发IO的keep alilve方案,满足一下几个需求

  1. 每个IO都是自己的时间戳
  2. 每个IO收到自己的beat后,重置自己的定时器
  3. 若IO定时没有收到beat,则执行IO的回调函数,并重置定时器
  4. 若再次没有收到beat,销毁IO,注销定时器。

案例二、设计一个线程或者进程的运行体R与运行体调度器S的结构体

  1. 运行体R:包含运行状态{新建,准备,挂起{IO等待读, IO等待写, 睡眠,延时}, 退出},运行体 回调函数,回调参数
  2. 调度器S:包含栈指针,栈大小,当前运行体
  3. 调度器S:包含执行集合{就绪,延时,睡眠,等待}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值