红黑树

简介: 红黑树

1 介绍

引入:二叉排序树当本来数据列表就已经是有序的,若采用就是蜕化成链表。故引入平衡树,而对于AVL是绝对平衡的,在工业生产中应用较少,故采用平衡规则没有那么严格的相对平衡的红黑树。

本文章主要总结红黑树的性质,应用场景,以及简单的实现一个红黑树的旋转,插入,删除等操作。

应用场景:nginx定时器,内存管理,linux内核线程调度,hashmap等

常见的两种工业用法:
1 以key_value方式主要用于查找,性能快O(logn)
2 使用中序遍历,得到有序数据。

2 定义性质

1:每个节点是红的或者黑的

2:根节点是黑色的

3:每个叶子节点是黑的

4:如果一个节点是红的,则它的两个儿子都是黑的

5:对每个节点,从该节点到其子孙节点的所有路径上包含相同数目的黑节点

注意:主要平衡的是黑色结点的高度,而红色主要是用来做选择判断用途

3 数据结构

一般情况下业务要与红黑树的性质进行分离的,这里只是为了搞理清流程。故就暂时未分离

结点

typedef int KEY_VALUE;
//结点
typedef struct _rbtree_node{
        unsigned char color;//颜色
        struct rbtree_node *left; //左子树
        struct rbtree_node *right;//右子树
        struct rbtree_node *parent; //父结点
        KEY_VALUE key;
        void *value; //存储具体的数据
}rbtree_node;

红黑树的结构

typedef struct _rbtree{
        struct _rbtree_node *root;    //根结点
        struct _rbtree_node *nil;       //叶子结点全部隐藏
}rbtree;

4 左右旋转

旋转主要为了达到黑结点高度一致的问题

主要是操作3对指针,总共6跟指针。

左旋具体流程图:

代码实现

//红黑树的旋转 主要是为了平衡黑高
//红黑树 + 当前结点
void rbtree_left_rotate(rbtree *T, rbtree_node *x){
        rbtree_node *y = x->right;     // 找到轴心y结点
        //x y都已经拿到  操作3对指针,6个指针
        //第一步 把
        x->right = y->left;
        if(y->left != T->nil){
                y->left->parent = x;//第二步
        }
        y->parent = x->parent;         //第三步
        if (x->parent == T->nil){   //第四步 //代表x是root
                T->root = y;
        }else if (x == x->parent->left){
                x->parent->left = y;
        }else{
                x->parent->right = y;
        }
        y->left = x;         //第五部
        x->parent = y;     //第六步
}

对于右旋转:将rbtree_left_rotate函数中的x–>y y–>x right–>left left—>right

代码实现:

void rbtree_right_rotate(rbtree *T, rbtree_node *y){
        // 找到轴心y结点
        rbtree_node *x = y->left;
        //x y都已经拿到  操作3对指针,6个指针
        
        //第一步 把
        y->left = x->right;
        if(x->right != T->nil){
                //第二步
                x->right->parent = y;
        }
        //第三步
        x->parent = y->parent;
        //第四步
        if (y->parent == T->nil){ //代表x是root
                T->root = x;
        }else if (y == y->parent->right){
                y->parent->right = x;
        }else{
                y->parent->left = x;
        }
        //第五部
        x->left = y;
        //第六步
        y->parent = x;
}

5 插入的三种情况

插入不会引起旋转,是插入完成后调整会引起旋转

插入之前就已经是一个红黑树,通过左旋或者右旋可以改变黑高

6 删除四种情况

完整代码参考:

https://github.com/hengfengyaoren/Data-Structure-Algorithm/blob/main/rbtree.c

目录
相关文章
原理篇:Seata TCC模式是如何解决幂等性、资源悬挂、空回滚问题的
原理篇:Seata TCC模式是如何解决幂等性、资源悬挂、空回滚问题的
1727 0
|
SQL 关系型数据库 数据库
学习分布式事务Seata看这一篇就够了,建议收藏
学习分布式事务Seata看这一篇就够了,建议收藏
23561 2
|
9月前
|
Java Spring 容器
SpringBoot自动配置的原理是什么?
Spring Boot自动配置核心在于@EnableAutoConfiguration注解,它通过@Import导入配置选择器,加载META-INF/spring.factories中定义的自动配置类。这些类根据@Conditional系列注解判断是否生效。但Spring Boot 3.0后已弃用spring.factories,改用新格式的.imports文件进行配置。
1295 0
|
弹性计算 安全 网络安全
转发路由器 Transit Router(TR):实现企业级互联网络的灵活与可靠
转发路由器 Transit Router(简称“TR”)是地域范围内企业级核心转发网元,可为用户转发同地域或不同地域的网络实例间的流量,并支持在地域内定义灵活的互通、隔离、引流策略,帮助用户打造一张灵活、可靠、大规模的企业级互联网络。通过搭配云数据传输(简称“CDT”),用户可实现跨地域连接场景数据传输按流量计费的能力。
|
负载均衡 Dubbo Java
Spring Cloud Alibaba与Spring Cloud区别和联系?
Spring Cloud Alibaba与Spring Cloud区别和联系?
|
弹性计算 安全 数据可视化
转发路由器 Transit Router体验评测
从初识到动手实操,全方面了解转发路由器 Transit Router
61194 26
转发路由器 Transit Router体验评测
|
开发框架 Java 开发者
Spring Boot中的自动装配原理
Spring Boot中的自动装配原理
3755 1
|
SQL 缓存 搜索推荐
分布式事务简介(seata)
分布式事务简介(seata)
800 0
|
SQL 算法 druid
「704. 二分查找 」| leetcode 刷题009
题目1 统计字符串中的单词个数,这里的单词指的是连续的不是空格的字符。 请注意,你可以假定字符串里不包括任何不可打印的字符。 示例: 输入: "Hello, my name is John" 输出: 5 解答 class Solutio...
1060 0

热门文章

最新文章