【C语言】红黑树

简介: 【C语言】红黑树

红黑树

1.二叉查找树

首先要了解的是二叉查找树,也称为二叉排序树,优点是在节点均匀分布的情况下,查找效率更高,缺点是,如果节点分布在一侧,查找时间就会约等于数组从头到尾的去查找。

  • 二叉查找树的子树都是二叉查找树。
  • 左子树都小于根节点,右子树都大于根节点

2.平衡二叉查找树

其次,平衡二叉查找树,也称为AVL树,AVL是它的两个发明者的名字组成。它有一套插入,删除的平衡机制,让插入删除后使用相应的平衡算法,再次成为AVL树,这样可以让每次的最坏查找时间接近O(logn),缺点是用于平衡的开销太大。

  • AVL树的子树都是AVL树
  • 左右子树的高度差小于等于1

3.红黑树

红黑树(Red Black Tree)是一种 二叉查找树,它并不是严格意义上的平衡二叉树,因为它有自己的平衡规则,和平衡二叉树规则不一样。它的查找,插入,删除的时间复杂度都是O(logn),n是指树中元素的个数。因此它在查找,插入,删除的最坏情况下运行时间很好。

​ 为什么查找,插入,删除的复杂度都是O(logn),因为红黑树自己有一套规则,去保持红黑树插入删除后还是红黑树。红黑树的平衡次数,相对于普通平衡二叉树少,开销更小。

  • 结点是红色或黑色(一个节点要么是红色,要么是黑色)
  • 根结点是黑色
  • 所有叶子都是黑色。(叶子是NIL结点)
  • 每个红色结点的两个子结点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色结点)
  • 从任一结点到其每个叶子的所有路径都包含相同数目的黑色结点。

红黑树用在哪些地方:hashmap,cfs,epoll,定时器,nginx中

使用红黑树,

​ 第一,主要是使用它的(key,value)属性,使用key可以去树上查找相应的value

​ 第二,它是一个二叉排序树,中序遍历是顺序的,可以查一个范围,例如比某个key小的有哪些

1.定义一颗红黑树

typedef int KEY_TYPE;
//定义红黑树节点
typedef struct _rbtree_node
{
   
   
    KEY_TYPE key;
    void *value;
    struct _rbtree_node *right;
    struct _rbtree_node *left;
    struct _rbtree_node *parent;
    unsigned char color;
} rbtree_node;

//定义红黑树
typedef struct _rbtree
{
   
   
    //红黑树的根
    rbtree_node *root;
    //红黑树叶子节点
    rbtree_node *nil;
} rbtree;

2. 红黑树旋转

红黑树的插入,删除,会导致不平衡,需要旋转和变色
在这里插入图片描述

2.1 左旋

这里仅仅是旋转,是因为不满足上述5条红黑树性质而进行的旋转。与平衡二叉树的旋转不一样。

因此,只需要考虑旋转点与它的父节点之间的左旋。

// T是树根节点,x是旋转轴节点的父节点
void rbtree_left_rotate(rbtree *T, rbtree_node *x)
{
   
   
    //y为旋转轴节点
    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;
    }

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

2.2 右旋

将左旋代码的x改为y,left改为right即可

目录
相关文章
|
3月前
|
存储 算法 C语言
"揭秘C语言中的王者之树——红黑树:一场数据结构与算法的华丽舞蹈,让你的程序效率飙升,直击性能巅峰!"
【8月更文挑战第20天】红黑树是自平衡二叉查找树,通过旋转和重着色保持平衡,确保高效执行插入、删除和查找操作,时间复杂度为O(log n)。本文介绍红黑树的基本属性、存储结构及其C语言实现。红黑树遵循五项基本规则以保持平衡状态。在C语言中,节点包含数据、颜色、父节点和子节点指针。文章提供了一个示例代码框架,用于创建节点、插入节点并执行必要的修复操作以维护红黑树的特性。
102 1
|
6月前
|
Java C语言 C++
从C语言到C++_28(红黑树RedBlackTree)概念+插入接口实现(上)
从C语言到C++_28(红黑树RedBlackTree)概念+插入接口实现
53 4
|
6月前
|
C语言
从C语言到C++_29(红黑树封装set和map)红黑树迭代器的实现(下)
从C语言到C++_29(红黑树封装set和map)红黑树迭代器的实现
47 3
|
6月前
|
编译器 测试技术 C语言
从C语言到C++_29(红黑树封装set和map)红黑树迭代器的实现(上)
从C语言到C++_29(红黑树封装set和map)红黑树迭代器的实现
39 0
|
6月前
|
算法 Java Linux
从C语言到C++_28(红黑树RedBlackTree)概念+插入接口实现(下)
从C语言到C++_28(红黑树RedBlackTree)概念+插入接口实现
37 0
|
6月前
|
算法 Java 应用服务中间件
C语言 红黑树分析与实现
红黑树的资料网上资料很多,对红黑树的定义、性质、以及操作都做了详细的分析,这篇博文也参考了网上的部分文章,不过主要是学习了腾讯课堂-零声king老师的课之后,对红黑树的一些理解。肯定有一些错误的地方,如果觉得不对,可以给我指出
78 0
|
1月前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
34 3
|
8天前
|
C语言
c语言调用的函数的声明
被调用的函数的声明: 一个函数调用另一个函数需具备的条件: 首先被调用的函数必须是已经存在的函数,即头文件中存在或已经定义过; 如果使用库函数,一般应该在本文件开头用#include命令将调用有关库函数时在所需要用到的信息“包含”到本文件中。.h文件是头文件所用的后缀。 如果使用用户自己定义的函数,而且该函数与使用它的函数在同一个文件中,一般还应该在主调函数中对被调用的函数做声明。 如果被调用的函数定义出现在主调函数之前可以不必声明。 如果已在所有函数定义之前,在函数的外部已做了函数声明,则在各个主调函数中不必多所调用的函数在做声明
25 6
|
28天前
|
存储 缓存 C语言
【c语言】简单的算术操作符、输入输出函数
本文介绍了C语言中的算术操作符、赋值操作符、单目操作符以及输入输出函数 `printf` 和 `scanf` 的基本用法。算术操作符包括加、减、乘、除和求余,其中除法和求余运算有特殊规则。赋值操作符用于给变量赋值,并支持复合赋值。单目操作符包括自增自减、正负号和强制类型转换。输入输出函数 `printf` 和 `scanf` 用于格式化输入和输出,支持多种占位符和格式控制。通过示例代码详细解释了这些操作符和函数的使用方法。
35 10
|
22天前
|
存储 算法 程序员
C语言:库函数
C语言的库函数是预定义的函数,用于执行常见的编程任务,如输入输出、字符串处理、数学运算等。使用库函数可以简化编程工作,提高开发效率。C标准库提供了丰富的函数,满足各种需求。