红黑树(三)删除

【数据结构】树(三):红黑树插入与删除操作(C++实现) 红黑树性质及操作分析,包含C++代码实现 阅读详情

删除操作比插入复杂一些。首先我们先来了解一些红黑树的特性。这些是我随意列举的,供大家参考。

  1、红色节点的父亲黑孩子一定是黑色。(nil是黑节点)

  2、单支节点,只能是黑红。(红黑,黑黑,不符合规则4,到树尾黑节点个数相同)

  3、真正的删除节点一定是单支节点或者叶子节点。(没有孩子的节点)

接下来我们讲如何找真正的删除节点。

有左右子树的情况

如果8是删除节点,那么10就是真正的删除节点。

查找方法是,找8节点的右子树中的最小的节点,根据二叉树的性质,我们可以知道,8节点的右孩子的左孩子的左孩子……一直到left为nil的节点。就是10。(while ( y->left != nil )  y = y->left;)

单支节点或者没有叶子节点的情况

删除节点跟真正的删除节点是一个。

找到真正的删除节点后,我们把删除节点的值变成真正的删除节点的值。这时候把真正的删除节点从红黑树中剔除。

如果真正的删除节点是黑色,则破坏了红黑树的性质,进行调整。(比如删除8,真正的删除节点是10,10是黑色节点,所以需要调整红黑树)

复制代码
void rb_remove(const int key, Tree * tree)
{
    Node * x, * y, * z;//x是删除点,y是真正的删除点,z是y的子节点

    x = search_node(key, tree);
    if ( x == nil || x->value != key )
        return;
    if ( x->left != nil && x->right != nil )//找到真正的删除节点
    {
        y = x->right;
        while ( y->left != nil )
            y = y->left;
    }
    else
        y = x;
    if ( y->left != nil )
        z = y->left;
    else
        z = y->right;
    
    if ( y == tree->root )
    {
        tree->root = z;
        z->parent = nil;
    }
    else
    {
        if ( y == y->parent->left )
            y->parent->left = z;
        else
            y->parent->right = z;
        if ( z != nil )
            z->parent = y->parent;
    }
    assign(x, y);

    if ( y->color == black )
        remove_fixup(z, y->parent, tree);
    free(y);
}
复制代码

在将真正的删除节点剔除时,注意它是否有孩子,如果右孩子,将原来指向真正删除节点的指针指向孩子,不要忘了将更改孩子的父亲。否则将原来指向真正删除节点的指针指向nil。

接下来删除调整

删除调整的实现有很多种,不过答题思路都是一样的。如果自己写的话,需要把各种情况考虑清楚。

复制代码
static void remove_fixup(Node * x, Node * y, Tree * tree)
{
    Node * z;//z是x的兄弟

    while ( x != tree->root && x->color == black )
    {
        if ( x == y->left )
        {
            z = y->right;
            //case 1:    兄弟是红色
            //处理方法:
            //        1.将兄弟设为黑色
            //        2.将父亲设为红色
            //        3.以父亲为旋转点,左旋
            //        4.重置x的兄弟节点
            //    变成case 2, 3, 4
            if ( z->color == red )
            {
                z->color = black;
                y->color = red;
                left_rotate(y, tree);
                z = y->right;
            }
            //case 2:    兄弟是黑色,并且两个孩子是黑色
            //处理方法:
            //        1.将兄弟设为红色
            //        2.将x设为父亲
            if ( z->left->color == black && z->right->color == black )
            {
                z->color = red;
                x = y;
                y = x->parent;
            }
            //case 3:    兄弟是黑色,左孩子是红色,右孩子是黑色
            //处理方法;
            //        1.将兄弟的左孩子设为黑色
            //        2.将兄弟设为红色
            //        3.以兄弟为旋转点,右旋
            //        4.重新设置兄弟节点
            else 
            {
                if ( z->right->color == black )
                {
                    z->left->color = black;
                    z->color = red;
                    right_rotate(z, tree);
                    z = y->right;
                }
                //case 4:    兄弟是黑色,右孩子是红色
                //处理方法:
                //        1.将兄弟的颜色设为父亲的颜色
                //        2.将父亲的颜色设为黑色
                //        3.将兄弟的右孩子设为黑色
                //        4.以父亲为旋转点,左旋
                z->color = y->color;
                y->color = black;
                z->right->color = black;
                left_rotate(y, tree);
                break;
            }
        }
        else
        {
            z = y->left;

            if ( z->color == red )
            {
                y->color = red;
                z->color = black;
                right_rotate(y, tree);
                z = y->left;
            }
            if ( z->left->color == black && z->right->color == black )
            {
                z->color = red;
                x = y;
                y = x->parent;
            }
            else
            {
                if ( z->left->color == black )
                {
                    z->right->color = black;
                    z->color = red;
                    left_rotate(z, tree);
                    z = y->left;
                }

                z->color = y->color;
                y->color = black;
                z->left->color = black;
                right_rotate(y, tree);
                break;
            }
        }
    }
    if ( x != nil )
        x->color = black;
}
复制代码

如果x是y的右孩子,操作跟左孩子相同,把left与right交换。

删除操作完成,建议大家在调试把红黑树画出来。

这里附上我的调试代码。

复制代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include "rbtree.h"

void print(Node * x)
{
    printf("%d\t", x->value);
    if ( x->color == red )
        printf("red\t");
    else
        printf("black\t");
    if ( x->parent )
        printf("parent value = %d\n", x->parent->value);
    else
        printf("\n");
}

int main(void)
{
    Tree tree;
    int i;
    
    srand(time(NULL));

    rb_init(&tree);

    for ( i = 0; i < 100; i++ )
    {
        rb_insert(rand()%1000, &tree);
    }

    rb_treaverse(&tree, print);
    for ( i = 0; i < 100; i++ )
    {
        rb_remove(rand()%1000, &tree);
    }

//    rb_insert(10, &tree);
//    rb_insert(7, &tree);
//    rb_insert(8, &tree);
//    rb_insert(15, &tree);
//    rb_insert(5, &tree);
//    rb_insert(6, &tree);
//    rb_insert(11, &tree);
//    rb_insert(13, &tree);
//    rb_insert(12, &tree);
//    rb_insert(2, &tree);
//
//    rb_treaverse(&tree, print);
//    rb_remove(5, &tree);
//    rb_remove(7, &tree);
//    rb_remove(6, &tree);
//    rb_remove(8, &tree);
//    rb_treaverse(&tree, print);
//    rb_remove(2, &tree);
//    rb_remove(10, &tree);
//    rb_remove(11, &tree);
//    rb_remove(12, &tree);
//    rb_remove(15, &tree);
//    rb_remove(13, &tree);

    rb_treaverse(&tree, print);

    return 0;
}
复制代码

前边的两个for循环主要测试红黑树是否有bug,如果发现bug,用下面的插入查找bug。

下边的代码四种情况基本都会用到。

YOLOv5 改进点总览:轻量化、高精度的背后有哪些魔改? YOLOv5是由Ultralytics团队开发的高效目标检测模型,其核心改进包括:主干网络采用CSPDarknet53提升梯度传播效率;特征融合使用PANet增强小目标识别;输出结构采用解耦头设计优化定位和分类任务。此外,YOLOv5通过CIoU损失函数、Mosaic数据增强和SimOTA标签分配机制进一步提升性能。模型支持多种推理格式(ONNX/TensorRT等),并具备自动锚框匹配和多尺度训练功能,使其在轻量化(yolov5s仅7MB)与高性能(最高51.2% mAP)间取得平衡,但缺乏正式论文支撑是 阅读详情

相关推荐

COMSOL后处理与可视化

公众号→【COMSOL仿真交流】←更多精彩内容 后处理是采用COMSOL建模的一个重要环节。通过软件自带的可视化工具,可以快速方便的展现仿真结果。 COMSOL为使用者提供了多种后处理工具,包括表面图、切面图、等值线图、流线图、线图、体图等等。可按功能分为数据集(储存数据的地方)、派生值和表单(对数据进行进一步的操作)、绘图组合绘图类型(显示数据结果的地方)、导出数据与生成报告。   如果想用origin、matlab对模拟数据做进一步的处理,导出excel格式的模拟结果,这可以通过“导出

midiio的博客 4027

红黑树删除节点——这一篇就够了

红黑树 红黑树常用的操作是插入、删除和查找,并且它对插入时间、删除时间和查找时间提供了最好可能的最坏情况担保,对于红黑树的概念、性质、插入、查找和旋转等这里不再多讲,不了解的请点击wikipedia rb-tree,这里重点讲一下红黑树的删除,这是红黑树中最难但又必须使用的操作。 红黑树的5条性质: 节点是红色或黑色。 根是黑色。 所有叶子都是黑色(叶子是NIL节点)。 每个红色节点的父子节点都...

liufangping的博客 1万+

SECS/GEM EAP 设备自动化功能原理和设计方案

半导体SECS GEMEAP实现了对生产线上机台的实时监控,是工厂自动化不可缺少的控制系统。EAP系统与FAB中的机台紧密相关,系统的设计与开发必须与生产线的机台实际生产流程相一致,才能达到控制机台生产的目的。 EAP SECS/GEM是MES与设备的桥梁,EAP通过SECS国际标准协议与机台进行数据传输。SECS是半导体设备(半导体行业称设备为机台)必须遵循的一种国际通信协议。EAP就是通过SECS与设备通信、传输数据、发送指令控制设备按照预先定义........

semisecs 17万+

数据结构——红黑树的删除节点操作

1. 红黑树的删除操作过程分析 1. 首先看一下普通搜索二叉树的删除操作,普通搜索二叉树删除结点找替代结点有3种情情景: 情景1:删除结点无子结点,直接删除 情景2:删除结点只有一个子结点 情景3:删除结点有两个子结点 在这里有一个重要的思路:删除结点被替代后...

chuangyangza0583的博客 1457

Qupath软件的安装与使用

Qupath软件的安装与使用软件安装软件下载软件安装【windows版】简单使用文件打开人工标注标注导出和导入 Qupath是一款开源的医学图像标注软件,适合放射影像及数字病理切片等的查看。同时,其自带的标注功能使得医生可以直接通过该软件进行病变区域的标注和分类。跟进一步的,该软件提供groovy脚本运行接口,可供操作者编写和运行脚本,将标注信息转换为xml或者json格式的数据进行进一步的后序处...

qq_40662074的博客 3万+

如何有效爬取“好大夫”评论数据?技术实现与合规性分析

本文探讨了爬取好大夫在线医生评论数据的技术与合规性问题。分析了好大夫平台评论数据的价值和特点,指出其动态加载和反爬机制的挑战。技术上,推荐使用Selenium模拟浏览器行为获取数据,并提供了分页爬取、代理IP、验证码识别等解决方案。同时强调必须遵守平台的爬虫策略,关注用户协议和隐私保护法规,建议通过官方API或授权方式获取数据。文章还讨论了数据清洗存储方法,并提醒注意数据伦理和最小化抓取原则。本文为医疗数据爬取提供了技术实现和合规性指导的平衡方案。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1052

红黑树详解三:红黑树的删除

系列文章目录 文章目录系列文章目录1、删除2、红黑树的平衡2.1、N为根节点2.2、兄弟为黑色节点2.2.1、兄弟子节点全黑2.2.1.1、父亲为红色节点2.2.1.2、父亲为黑色节点2.2.2、兄弟子节点全为黑(全红,一红一黑)2.2.2.1、兄节点与为红色的兄子节点同边2.2.2.1.1、兄在左,凶左子为红2.2.2.1.2、兄在右,凶右子为红2.2.2.2、兄节点与红色的兄子节点异边 1、删除 红黑树的删除和二叉搜索树类似,只不过需要加上颜色,经过变色和旋转满足红黑树的性质。 大致情况为如下几种,

zhengguofeng0328的博客 1863

OBS技术深度剖析:从开源直播工具到专业制作引擎的进化之路

本文深入剖析了开源直播软件OBS的技术架构与发展历程。从2012年诞生至今,OBS已成长为直播领域的事实标准,其成功源于模块化设计和开源协作模式。文章详细解析了OBS的核心技术:1) 分层架构与插件系统,2) GPU加速的渲染管线,3) 智能音频处理,4) 多平台编码优化。同时探讨了虚拟摄像头、浏览器源等高级功能的实现原理,并提供了性能优化方案和硬件配置建议。随着AI、WebRTC等新技术发展,OBS将持续引领实时内容创作工具的创新,为开发者和创作者提供更强大的技术支持。

程序猿老樊的博客 325

数据结构-----红黑树的删除操作

只有流过血的手指,才能弹出世间的绝唱。—— 泰戈尔今天我们接着学习红黑树,前面学习了红黑树的插入操作,那这次就学习红黑树的删除操作,相较于红黑树的插入操作,红黑树的删除操作更加复杂,但是别急,下面我会非常详细的去讨论这个过程,以及提供完整的代码,好了,开始上正文。相关链接数据结构-----红黑树简介_Gretel Tade的博客-优快云博客数据结构-----红黑树的插入_Gretel Tade的博客-优快云博客),这个是一个红黑树模拟器的网址,你们可以去进行红黑树插入删除遍历等操作,可以自己试试看。

m0_73633088的博客 2702

全网最全-DA14531-全球最小-BLE从入门到精通开发教程

本教程主要适用于低功耗产品,DA14531它体积小,非常适用于对体积敏感的设备,如无线可穿戴、传感器、助听器等设备。本文经过作者发大量时间来记录开发项目的调试方法,里面有许多笔者开发心得体会,旨在让读者工程师快速上手,减少摸索时间,提高软件质量。读者对象本文档主要适用以下工程师:嵌入式系统工程师单片机软件工程师IOT固件工程师BLE固件工程师。

hejinwu1314的博客 5137

解锁轻量化网络实验室:在 Containerlab 中部署 Cisco IOL 设备的详细教程

Cisco IOS On Linux(IOL)是 Cisco IOS-XE 的简化版,它是 Cisco IOS 的一种轻量级实现。IOL 并不需要完整的虚拟机(Virtual Machine, VM)环境,可以直接在 Linux 上运行,极大地减少了对系统资源的需求。IOL 节点通过更精简的方式提供了 Cisco IOS 功能,适合构建实验室、测试网络协议和验证网络设计。

网络技术联盟站 476

红黑树系列三:红黑树的删除

一、红黑树定义  红黑树需要满足下面4个条件:      1、每个节点不是红色就是黑色。      2、根节点为黑色。      3、如果节点为红色,其子节点必须为黑色。      4、任意一个节点到到NULL(树尾端)的任何路径,所含之黑色节点数必须相同。 二、红黑树的删除 对二叉查找树,我们知道删除的结点可能有三种情况:(1)为叶子结点,(2)左子树或右子树有

lpp0900320123的专栏 1930

基于STM32设计的计算器(实现基本运算)

当前文章介绍的是STM32+LCD触摸屏设计的一个触摸计算器功能,实现基本的加减乘除,二进制转换显示等功能。LCD屏使用的是3.5寸带触摸屏的显示屏,方便操作屏幕,MCU采用STM32F103ZET6。

8817

红黑书(三)红黑树的删除操作

c++完整代码(带插入、删除、查找等): #include <iostream> using namespace std; #include <stack>//颜色枚举; enum _color { _None, _Red, _Black }; //结点结构; struct tNode { int iKey; int iColor; tNode* pP

love_jing_forever的博客 600

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

红黑树(三)----删除的情况

详解红黑树删除的情况

m0_73537205的博客 1013

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

红黑树原理及插入、删除——基于树的查找(三)

红黑树 红黑树(red-black tree)是一种自平衡二叉查找树。 一颗红黑树是满足下面性质的染色二叉排序树: 结点是红色或黑色; 根结点是黑色; 每个叶节点(NIL节点,空节点)是黑色的; 每个红色结点的左右子结点都是黑色; 从任一结点到其每个叶子的所有路径都包含相同数目的黑色结点。 可以看出,在一棵红黑树中,最短的道路是所有的结点都是黑色的,最长的道路必是红黑相间。...

weixin_39651041的博客 3422

红黑树基础与代码 - 节点的删除(三)

1.节点的删除 红黑树与二叉搜索树的删除节点过程一样,当删除节点存在两个子节点,会被转换为删除有一个子节点或不存在子节点的节点。 对于有一个子节点的节点删除,比较简单,不需要平衡调整,只需要将其子节点改为黑色即可。 2.删除规则 对于删除的节点有两个不为空的叶子节点,这种情况最为复杂,需要平衡调整。 删除节点平衡调整的情况有如下几种 待删除节点的兄弟节点是红色 待删除节点的兄弟节点是黑色,且兄弟...

WQ_631288233的博客 396

【数据结构三】RBTree红黑树代码测试, 添加 ,删除

6.5测试类 文章目录6.5测试类添加测试类1`TreeOperation`2添加测试类2`RBTreeTest`3, RBTreeput方法测试运行结果网站验证remove方法测试 (前驱) 添加测试类1TreeOperation package com.ccc.util.treemap; public class TreeOperation { /* 树的结构示例: 1 / \ 2 3

xbd_zc的博客 1459

数据结构之红黑树(三)——删除操作

删除一个节点同样有可能改变树的平衡性,而且,删除所造成的不平衡性比插入所造成的平衡性的修正更加复杂。 化繁为简是算法分析中一个常用的方法。下面我们将欲删除节点分为三大类:欲删除节点为叶子节点、欲删除节点只有一个子节点和欲删除有两个子节点。 而欲删除节点有两种可能的颜色,也需要分别对待。 为简化讨论,我们以欲删除节点在左侧的情况为例进行修正,如果欲删除节点在右侧,进行镜像地修正操作

SuYuMingXiangGuan的博客 728

二叉树之红黑树的实现-插入和删除(三)

#include <stdio.h> #include <stdlib.h> ////////////////////////////////////////////////////////////////////// #define RED ...

chenqugu1289的博客 266
上一篇: 红黑树(二)插入
下一篇: 轻松掌握KMP算法 字符串匹配
! 不再维护
博客等级 码龄11年 63粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值