红黑树学习

news2024/11/28 21:50:45

              

红黑树:

 k v 方式

用在哪里:

1.hash

 强查找的过程:

 1.rbtree

 2.hash

 3.b/b+ tree

 4.链表

 红黑树:

 1.每个结点是红的或者是黑的

 2.根结点是黑的

 3.每个叶子结点是黑的

 4.如果一个结点是红的,则它的两个儿子是黑的

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

红黑树在插入任何一个结点之前,就是一颗红黑树

左旋:

右旋:

插入:

1.先找到合适的位置

2.先插入节点默认为红色,后面再进行调整

插入调整:

// 定义键类型的别名
typedef int KEY_TYPE;

// 定义红色和黑色的宏
#define RED 0
#define BLACK 1

// 定义红黑树节点结构的宏
#define RBTREE_ENTRY(name, type) \
    struct name                  \
    {                            \
        struct type *left;       \
        struct type *right;      \
                                 \
        struct type *parent;     \
                                 \
        unsigned char color;     \
    }

// 定义红黑树节点结构
typedef struct _rbtree_node
{
    KEY_TYPE key; // 节点键值
    void *value;  // 节点关联的值

#if 1
    struct rbtree_node *left;   // 左子节点指针
    struct rbtree_node *right;  // 右子节点指针
    struct rbtree_node *parent; // 父节点指针
    unsigned char color;        // 节点颜色
#else
    RBTREE_ENTRY(, rbtree_node) // 使用宏定义节点结构
    node;
#endif

} rbtree_node;

// 定义红黑树结构
typedef struct _rbtree
{
    rbtree_node *root; // 根节点指针
    rbtree_node *nil;  // 默认黑色空节点
} rbtree;

// 左旋操作
void rbtree_left_rotate(rbtree *tree, rbtree_node *x)
{
    // x的右子节点
    rbtree_node *y = x->right;

    // 1. 把y的左子节点变成x的右子节点
    x->right = y->left;
    if (y->left != tree->nil)
        y->left->parent = x;

    // 2. 把x变成y的左子节点
    y->parent = x->parent;
    if (x->parent == tree->nil)
        tree->root = y;
    else if (x == x->parent->left)
        x->parent->left = y;
    else
        x->parent->right = y;

    // 3. 把x变成y的左子节点
    y->left = x;
    x->parent = y;
}

// 右旋操作
void rbtree_right_rotate(rbtree *tree, rbtree_node *x)
{
    // x的左子节点
    rbtree_node *y = x->left;

    // 1. 把x的左子节点变成y的右子节点
    y->left = x->right;
    if (x->right != tree->nil)
        x->right->parent = y;

    // 2. 把y变成x的右子节点
    x->parent = y->parent;
    if (y->parent == tree->nil)
        tree->root = x;
    else if (y == y->parent->left)
        y->parent->left = x;
    else
        y->parent->right = x;

    // 3. 把y变成x的左子节点
    x->right = y;
    y->parent = x;
}

// 插入后修复红黑树性质
void rbtree_insert_fixup(rbtree *tree, rbtree_node *z)
{
    // 当z的父节点为红色时,需要修复红黑树性质
    while (z->parent->color == RED)
    {
        // 判断父节点是祖父节点的左子节点还是右子节点
        if (z->parent == z->parent->parent->left)
        {
            // 叔父节点
            rbtree_node *y = z->parent->right;
            if (y->color == RED)
            {
                // 情况1:父节点和叔父节点都是红色
                z->parent->color = BLACK;
                y->color = BLACK;
                z->parent->parent->color = RED;
                // 继续对祖父节点进行修复
                z = z->parent->parent;
            }
            else
            {
                // 情况2:父节点是红色,叔父节点是黑色
                if (z == z->parent->right)
                {
                    z = z->parent;
                    rbtree_right_rotate(tree, z);
                }

                // 情况3:父节点是红色,叔父节点是黑色
                if (z == z->parent->left)
                {
                    z->parent->color = BLACK;
                    z->parent->parent->color = RED;
                    rbtree_right_rotate(tree, z->parent->parent);
                }
            }
        }
        else
        {
            // 对称处理右子树的情况
        }
    }
}

// 插入节点到红黑树
void rbtree_insert(rbtree *t, rbtree_node *z)
{
    // 寻找插入位置
    rbtree_node *x = t->root;
    rbtree_node *y = t->nil;
    while (x != t->nil)
    {
        y = x;
        if (z->key < x->key)
        {
            x = x->left;
        }
        else if (z->key > x->key)
        {
            x = x->right;
        }
        else
        {
            // 如果键值已存在,则不插入
            return;
        }
    }

    // 将z插入到y的适当位置
    if (y->key >= z->key)
    {
        y->left = z;
    }
    else
    {
        y->right = z;
    }
    z->parent = y;
    z->left = t->nil;
    z->right = t->nil;
    z->color = RED;

    // 插入后修复红黑树性质
    rbtree_insert_fixup(t, z);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2192167.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

lrzsz串口文件传输

此时如果需要传输文件&#xff0c;需要借助rz/sz工具&#xff0c;可以使用的传输协议有ZMODEM、YMODEM、XMODEM&#xff0c;默认是ZMODEM。 https://en.wikipedia.org/wiki/ZMODEM https://gallium.inria.fr/~doligez/zmodem/zmodem.txt 这里记录item2下使用rz/sz进行文件传输…

AI驱动的数据智能化:如何提升企业数据处理效率?

在当今数据驱动的时代&#xff0c;企业需要高效、精准的方式来管理和查询日益增长的业务数据。AI技术在这个过程中发挥着至关重要的作用&#xff0c;它通过自动化、智能化的方式处理数据、构建知识模型、实现查询优化&#xff0c;并将复杂的数据结构直观地呈现出来。本文将通过…

Spring Boot 进阶-详解Spring Boot整合数据库

在Java企业级开发中,不可避免的要对数据进行持久化,我们常见的数据持久化的技术又Mybatis技术、Spring自带的JdbcTemplate以及SpringBoot中的JPA技术。但是无论怎么样的持久化技术,其底层都是离不开数据库的支持。 在刚开始学习Java操作数据库的时候,最长用到的技术就是JDB…

SpringBoot中间件Docker

Docker&#xff08;属于C/S架构软件&#xff09; 简介与概述 1.Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言 并遵从 Apache2.0 协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux …

Mysql数据库原理--查询收尾+索引+事务

文章目录 1.查询收尾1.1自查询1.2合并查询 2.索引事务2.1约束自动生成索引2.2create手动添加索引2.3.删除手动创建的索引2.4索引背后的数据结构2.5B树的结构特点和优点--经典面试题 3.事务--经典面试题3.1基本理解3.2事务的特性3.3隔离级别 1.查询收尾 1.1自查询 子查询就是套…

用Python实现运筹学——Day 13: 线性规划的高级应用

一、学习内容 1. 多目标线性规划 多目标线性规划&#xff08;MOLP&#xff09;是线性规划的扩展形式&#xff0c;涉及多个相互冲突的目标函数。这类问题在实际应用中非常普遍&#xff0c;例如在供应链管理中&#xff0c;可能需要同时优化成本、时间、质量等多个目标。由于多个…

MCU8.C51的一些知识补充

由于绝大部分的C语言知识已在C语言学习笔记专栏 点我跳转讲过,本文补充一些没有提到过的(C51标准) 1.C51扩充数据类型 sfr:特殊功能寄存器(special function register) sbit:是特殊功能寄存器(sfr)中的一个位的地址,用于直接定义和访问单个引脚的状态 sfr16:16位特殊功能寄存…

普通程序员如何入手学习大模型(LLM)附学习路线和资源教程

在人工智能&#xff08;AI&#xff09;飞速发展的今天&#xff0c;掌握AI技术已经成为了许多高校研究者和职场人士的必备技能。从深度学习到强化学习&#xff0c;从大模型训练到实际应用&#xff0c;AI技术的广度和深度不断拓展。作为一名AI学习者&#xff0c;面对浩瀚的知识海…

深度学习----------------------注意力机制

目录 心理学不随意线索随意线索 注意力机制非参注意力池化层Nadaraya-Watson核回归参数化的注意力机制 总结注意力汇聚&#xff1a;Nadaraya-Watson核回归代码生成数据集核回归非参数注意力汇聚注意力权重该部分总代码 带参数的注意力汇聚将训练数据集转换为键和值训练带参数的…

双11买什么东西比较好?买什么?这份双十一好物清单请查收

​双十一购物节是每年最大的购物狂欢节&#xff0c;很多商品都通过一定的优惠活动进行促销&#xff01;只不过有些朋友不知道这么大的活动力度&#xff0c;有哪些好物值得放心入手的&#xff01;于是小编根据这些年在双十一的选购经验&#xff0c;整理了一些实用的购物攻略建议…

新手入门大语言模型学习路线

最近有很多同学想要学习大模型&#xff0c;于是我根据多年的学习经验&#xff0c;总结了一些适合你从 0 到 1 的入门经验&#xff0c;分享给大家呀 1、几个学习大模型必备: 教程:动手学大模型Dive into LLMs 《动手学大模型 Dive into LLMs》&#xff1a;内容丰富&#xff0c…

Linux运维02:WM虚拟机安装Centos7操作系统

Centos7镜像文件下载链接&#xff1a;centos-7-isos-x86_64安装包下载_开源镜像站-阿里云 (aliyun.com)https://mirrors.aliyun.com/centos/7/isos/x86_64/ 1.点击“编辑虚拟机设置”、点击“CD/DVD”、点击“预览”选择镜像文件位置&#xff0c;点击“确定”&#xff1b; 2.点…

【STL】list模拟实现(画图万字解析+代码)

list模拟实现 1 模块分析1.1 list的结构1.2 ListNode的结构1.3 迭代器类 2 ListNode节点设计3 迭代器类设计3.1 迭代器类框架3.2 模板设计3.3 operator()前置和后置3.4 operator--()前置--和后置--3.4 operator*()3.5 operator->()3.6 operator!() 和 operator()3.7 迭代器类…

一张照片变换古风写真,Flux如何做到?

前言 解锁图像创作新体验&#xff1a;ComfyUI指南 在AI图像生成领域&#xff0c;ComfyUI 已成为不可忽视的力量。它是基于Stable Diffusion的图像生成工具&#xff0c;提供了一个节点式图形用户界面&#xff08;GUI&#xff09;&#xff0c;让用户可以通过简单的拖拽与配置来…

睡眠对于生活的重要性

在快节奏的现代生活中&#xff0c;健康养生不再是遥不可及的概念&#xff0c;而是融入日常每一刻的必需。其中&#xff0c;睡眠作为生命不可或缺的环节&#xff0c;其重要性往往被忽视&#xff0c;实则它是身体修复、能量积蓄的黄金时段。今天&#xff0c;让我们深入探讨“健康…

【橙子老哥】.NetCore 管道模型源码深度解读

hello&#xff0c;大家好&#xff0c;今天又是橙子老哥的分享时间&#xff0c;希望大家一起学习&#xff0c;一起进步。 欢迎加入.net意社区&#xff0c;第一时间了解我们的动态&#xff0c;地址&#xff1a;ccnetcore.com 最近遇到很多小伙伴们问我&#xff0c;自己会.netfr…

【电力系统】Matlab|含风电-光伏-光热电站电力系统N-k安全优化调度模型

摘要 本文提出了一种结合风电、光伏与光热电站的电力系统N-k安全优化调度模型。通过在电力系统中集成多种可再生能源发电技术&#xff0c;优化不同类型电源的调度策略&#xff0c;确保在N-k故障情景下系统的稳定运行。基于Matlab仿真&#xff0c;本文分析了可再生能源发电的功…

路由:ReactRouter

概述 一个路径path对应一个组件component 当我们在浏览器中访问一个path的时候&#xff0c;path对应的组件会在页面中进行渲染。 使用 快速开始 安装依赖 npm i react-router-dom基本使用 import { createBrowserRouter, RouterProvider } from react-router-domconst ro…

【JavaEE初阶】多线程案列之定时器的使用和内部原码模拟

前言&#xff1a; &#x1f308;上期博客&#xff1a;【JavaEE初阶】深入理解多线程阻塞队列的原理&#xff0c;如何实现生产者-消费者模型&#xff0c;以及服务器崩掉原因&#xff01;&#xff01;&#xff01;-CSDN博客 &#x1f525;感兴趣的小伙伴看一看小编主页&#xff1…

房地产销售|基于springBoot的房地产销售管理系统设计与实现(附项目源码+论文+数据库)

私信或留言即免费送开题报告和任务书&#xff08;可指定任意题目&#xff09; 目录 一、摘要 二、相关技术 三、系统设计 四、数据库设计 五、核心代码 六、论文参考 七、源码获取 一、摘要 社会和科技的不断进步带来更便利的生活&#xff0c;计算机技术也越来…