红黑树

简介: 红黑树

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

目录
相关文章
|
5月前
|
关系型数据库 容器
红黑树的简单介绍
红黑树的简单介绍
38 0
|
5月前
|
存储 应用服务中间件 调度
随处可见的红黑树详解
随处可见的红黑树详解
68 0
|
4月前
|
关系型数据库 C++
【c++】红黑树
【c++】红黑树
21 0
|
5月前
|
C++ 容器
【C++】红黑树(上)
【C++】红黑树(上)
|
5月前
|
算法 关系型数据库 Java
【C++】红黑树(下)
【C++】红黑树(下)
|
4月前
|
Linux 调度 数据库
红黑树详解
红黑树详解
|
5月前
|
Linux C++
红黑树的实现
红黑树的实现
32 2
|
5月前
|
调度
随处可见的红黑树
随处可见的红黑树
|
5月前
|
存储 Linux 调度
C++【红黑树】
C++【红黑树】
55 0