自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(66)
  • 收藏
  • 关注

原创 揭秘互联网的“第一道门”:初识 Socket 编程,亲手推开网络通信的奇妙世界

🔥❄️✨博主简介:前言:在上一篇文章中,我们沿着网络发展的长河,俯瞰了宏观的网络架构。然而,,掌握了地图并不等于真正开启了航行。今天,我们将正式踏入网络编程的实战疆域。作为开发者,我们要推开的第一扇大门,便是连接应用与网络的灵魂之桥——。接下来,请随我一起拨开云雾,深入探寻 Socket 的奥秘,听我慢慢道来。

2026-01-02 12:59:02 859 86

原创 万物互联的起点:走进 Linux 网络的心脏,开启一场从零开始的底层探索之旅

在上面我们说协议就是一个"约定",但毕竟这种说法还是太笼统了,而要弄清楚到底什么是协议这个问题的答案,我们就要达成两个共识,前面是第一个共识,下面我们还要达成一个共识:一个问题:OS系统一般是用什么语言来写的呢?答案很明显,是用C语言写的,而这就是我们要达成的第二个共识。而有了上面的两个共识之后我们再来思考一个问题:协议可不只有我们上面介绍的TCP/IP这两种的,是有很多种的,那么OS要不要管理这些协议呢?

2025-12-28 11:21:03 1708 70

原创 手撕 Linux 信号量:从古老的 PV 原语到现代内核,极致简洁的同步美学

在前面,我们讲解了线程互斥和线程同步的相关内容,但是既然谈到了线程的互斥与同步,就不得不提信号量了,这也是线程的互斥和同步这部分内容中不可忽视的一部分,那么今天我们就来深入探讨一下信号量,下面我们来一起看看吧。

2025-12-22 11:39:30 780 34

原创 一文读懂 Linux 线程同步:了解同步原语的设计哲学与实现

我们可以想一下在生活中,有哪些场景是符合生产和消费的场景?例如:网上购物,去超市购物,在游戏中买皮肤等等,这些都是具有生产者和消费者的场景,那么下面我就用超市来举例。我们首先先思考一个问题:超市是生产者吗?我们经常会去超市购物,所以我们都知道超市并不是生产者,而是起到一个商品汇聚,商品派发,是一个中间场所。而真正的生产者我们想必也都能想到,那就是超市这些商品的供应商,所以:所以完整的生产者和消费者就如上图所示,

2025-12-22 11:39:28 790 64

原创 一文读懂 Linux 互斥锁:小白也能看懂的临界区保护指南,手把手教你彻底告别多线程数据“打架”

在前面的章节中,我们了解了什么是线程,以及如何通过pthread库所提供的函数来对线程进行操作,但是我们要了解的不止有这些,我们创建多线程是为了让它们协作帮助我们去完成任务。而今天及后面的章节我们就将目光聚焦在线程之间协作的方面,了解线程之间协作时会出现什么样的问题以及如何解决,下面就开始我们今天的内容。

2025-12-17 10:48:52 1150 61

原创 Linux 线程控制的内功心法:详解 pthread 库函数背后的底层逻辑,手把手教你掌握线程生命周期的“生杀大权”

通过上一篇的初识线程的相关内容,我们此时对于线程已经有了大致的了解,而我们今天这篇就要深入线程,了解关于线程控制的相关知识,在今天这篇中我们会看到很多进程身上的影子,那么下面就跟我来看看吧!!!

2025-12-15 11:06:33 1161 57

原创 告别进程的单打独斗,迈入线程的高效协同:一文带你推开Linux线程世界的大门

在上一篇中我们结束了Linux信号章节的全部内容,下面我们将进入新的篇章:Linux线程而今天的这篇文章的主要内容是初识线程,帮助我们来迈进线程的大门,对Linux中的线程有个大概的了解,便于我们对后续内容的讲解。

2025-12-07 10:45:13 913 67

原创 Linux信号捕捉全解析:深入原理与实战,掌控进程的生命节拍

🔥海棠蚀omo:个人主页 ❄️个人专栏:《初识数据结构》,《C++:从入门到实践》,《Linux:从零基础到实践》 ✨追光的人,终会光芒万丈博主简介:​​​​​​目录一.信号捕捉的流程二.周边知识2.1硬件中断2.2时钟中断2.3软中断2.3.1从内核角度见一见系统调用2.3.2系统调用号 + 虚拟地址空间 + 软中断2.4写时拷贝??缺页中断??2.5 Sigaction函数在讲解下面的知识前,想必大家心中有疑惑:为什么同样都是信号处理,怎么不

2025-12-03 13:43:33 1063 65

原创 Linux信号保存的核心:未决信号集与阻塞信号集——探秘内核如何实现信号的阻塞、暂存与派发

我们前面在讲解信号产生的时候,说到进程在收到信号时可能并不会立即处理,既然不会处理那就要将信号保存起来,我们当时只简单讲解了在进程的PCB中会有一个位图来保存信号。而我们今天就来详细探讨一下关于信号保存方面更为详细的知识。

2025-11-29 10:47:00 1201 50

原创 解读Linux进程的“摩尔斯电码”:信号产生的原理与实践,掌控进程的生死时速

🔥海棠蚀omo:个人主页 ❄️个人专栏:《初识数据结构》,《C++:从入门到实践》,《Linux:从零基础到实践》 ✨追光的人,终会光芒万丈博主简介:​​​​​​目录一.现实--信号概念1.1信号是什么?1.2为什么会有信号?二.将信号从现实映射到计算机中三.部分Linux系统中产生信号的方式四.对信号本质的朴素认识四.Linux中其他产生信号的方式4.1系统调用4.1.1 kill

2025-11-26 12:46:06 880 63

原创 解剖System V共享内存:一段共享内存的“生命轨迹”与每一字节的归宿

🔥海棠蚀omo❄️个人专栏✨追光的人,终会光芒万丈博主简介:​​​​​上一篇我们讲了第一种进程间通信的方式:管道,而今天我们来讲第二种通信方式:System V,而在System V中,我们最需要掌握的就是其中共享内存的相关知识,下面跟着我来看看吧。

2025-11-22 09:30:00 3036 74

原创 管道如何连接进程?从基础原理到高级应用,构建你的进程通信全景视野

进程间通信,简称IPC,是指两个或多个进程之间进行数据交换信息传递或同步操作的机制。人与人之间交流沟通是在干什么?将进程间通信转换到人与人之间,换个问法相信大家就好理解多了,其实也就跟人与人之间交流沟通是很相似的。数据传输:⼀个进程需要将它的数据发送给另⼀个进程资源共享:多个进程之间共享同样的资源。通知事件:⼀个进程需要向另⼀个或⼀组进程发送消息,通知它(它们)发⽣了某种事件(如进程终⽌时要通知⽗进程)。

2025-11-19 17:13:48 2601 52

原创 从ELF的沉默到进程的喧嚣:解读Linux中动态链接如何激活一个可执行文件的完整生命

通过这张图我们就与前面讲的内容给串联起来,在这幅图中左边就是虚拟地址空间,中间就是我们前面讲过的文件系统,大家要弄清楚这之间的各种关系。

2025-11-15 13:57:06 1665 61

原创 当你说“运行程序”时,操作系统到底看到了什么?——ELF文件结构深度解析

🔥海棠蚀omo❄️个人专栏✨追光的人,终会光芒万丈博主简介:​​​我们在上一篇中详细讲了动静态库从制作到使用的各种细节,但是和动静态库相关联的不仅是上一篇的知识,还有动静态链接,而要说到动静态链接,就不得不了解一下ELF文件,所以我们今天就来好好聊聊ELF文件的各种细节。

2025-11-13 11:18:57 2893 58

原创 庖丁解牛:深入拆解Linux静态库与动态库——从制作到使用的核心技巧讲解

在讲解后面的知识前我们先要弄明白到底什么是库?简而言之,库是写好的现有的,成熟的,可以复⽤的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个⼈的代码都从零开始,因此库的存在意义⾮同寻常。在我们日常写C语言代码时,所包含的<stdio.h>,<string.h>等,其实就是库,或者严格来说是库的一部分,而为什么要有库的存在呢?

2025-11-11 13:13:17 1758 54

原创 深入理解Ext2:Linux文件系统的基石与它的设计哲学

这里我们随便创建一个文件,通过ls -li来查看文件的inode,可以看到我们新创建的文件inode非常小,通过比较可以看到在vda3分区中的inode和我们自己创建的分区中的inode还是有比较大的差异的,毕竟这些文件属于不同的分区。这个位图的道理和上面是一样的,同样将Inode Table中的每一个块都当作一个比特位,比特位的位置就是inode的位置,比特位的内容【0,1】,就表示对应的inode是否被占用,0就表示未被占用,1就表示被占用了。这样不就造成了很大的损失吗?

2025-11-08 11:19:43 2831 56

原创 Linux文件系统-从“物理盘片”到“逻辑结构”:文件系统如何为硬盘注入灵魂?

🔥海棠蚀omo❄️个人专栏✨追光的人,终会光芒万丈博主简介:​从最初讲解文件到现在,我们谈论的都是我们在最初提到文件时,说到文件分为打开的文件和未打开的文件,而未打开的文件我们当时说它们在硬盘中,那么既然我们要讲解未打开的文件,就有必要先了解一下硬盘的相关知识,这样我们才能更好的去理解何为文件系统。

2025-11-05 13:07:02 1288 58

原创 Linux基础I/O-缓冲区:系统大厨的“万能传菜员”与它的效率魔法

缓冲区是内存空间的⼀部分。也就是说,在内存空间中预留了⼀定的存储空间,这些存储空间⽤来缓冲输⼊或输出的数据,这部分预留的空间就叫做缓冲区。缓冲区根据其对应的是输⼊设备还是输出设备,分为输⼊缓冲区和输出缓冲区。直接说缓冲区的概念比较晦涩,不太好理解,下面我们从另一个角度来理解缓冲区。二.为什么要有缓冲区?

2025-11-03 12:50:36 1757 54

原创 Linux基础I/O-打开新世界的大门:文件描述符的“分身术”与高级重定向

也就是"hello world",但是是真的向文件内核缓冲区中写入内容吗?答案不是的,这里write函数真正做的是将用户定义的缓冲区内部保存的数据。

2025-11-01 12:01:49 1360 35

原创 Linux基础I/O:C语言文件操作“黑话”指南:读懂文件描述符的摩斯电码

我们在背景知识中说过要想对文件的内容进行操作,那么首先要做的就是打开文件,所以说上面的“ > ”在底层实现中同样也是和上面的w一样,清空文件,在将内容写入到文件中,他们的底层实现都是通过系统调用实现的,这点下面我们就会讲到。当然呢,关于文件的操作不止有w和a,除了这俩还有上面的一些,这里我没有讲r,因为r就是读文件,没什么可讲的,并且它也不是我们讲的重点,而剩下的后面有+号的都是既可以读又可以写的方式,为什么这些我没有讲呢?但是当我们再次执行后查看文件中的内容,发现我们新增的内容没有了,这是怎么回事呢?

2025-10-30 11:44:38 1817 49

原创 Linux操作系统-进程的“夺舍”:程序替换如何清空内存、注入新魂?

这里我们要用到main函数的参数argv,也就是我们之前讲过的命令行参数,我们让arg指针指向argv的第二个数据,因为第一个数据是我们要执行的文件,后面才是要怎么执行,并将argv的第一个数据传给execv的第一个参数,之后将arg指向的从下标为1开始的数组传给第二个参数。这里我以execvpe为例,我们这次让子进程来执行我们自己写的程序,程序的内容就是打印出命令行参数和环境变量,程序的结果我们也看到了命令行参数和环境变量的内容,其中环境变量就是我们所传进去的,并且命令行参数正是arg数组中的内容。

2025-10-27 15:14:15 1582 55

原创 Linux操作系统-父进程的等待:一个关于回收与终结的故事

我们在学习C语言的时候相比都接触过位运算,我们这里将status右移8位,就可以将后8位移到前8位,这样对应退出码的1就落在了最低位,并将右移的结果和0xFF进行按位与,0xFF我们应该也都认识,就是每个比特位都是1的数,经过上面的计算我们就能得到我们想要的推出码了。我们上面说了int* status指向了一个int类型的数据,int类型的大小是4个字节,也就是32个比特位,我们不关心前16个比特位,只看后16个比特位,而在后16个比特位中,后8位表示退出状态,也就是退出码。

2025-10-23 12:38:50 1468 68

原创 Linux操作系统-深入fork与进程终止:揭秘进程的优雅终局

相信我们在日常写代码时也会设置不同退出码,0表示成功就不说了,有时我们程序运行失败了会用1,会用2等退出码,而这些原因我们可以自己去制定,就比如某个值在运行过程中经过判断==0,我们此时就return 1,那么失败的原因就是这个数==0,不是我们想要的结果,我就让它结束了。这种现象相信我们在日常写代码中是遇到过的,因为我们的误操作,导致某个指针变成了野指针,并且我们还去访问这个野指针中的内容,那么此时启动程序后,程序直接就崩了,那就是操作系统终止了进程,这种情况和上面的类似。

2025-10-20 16:28:31 1625 55

原创 Linux操作系统-教你如何正确认识:命令行参数及环境变量

答案就在上面,像上面的./mycmd,which等命令后面跟的一些选项,它们本质是字符串,可以以一定的方式传递给which等内部的“ main ”函数,在which内部实现的时候,就可以根据不同的选项进行判定,而判定的大概逻辑就和上面差不多,从而实现类似的功能,输出你想要的内容。在Linux中大部分命令是可执行程序,需要通过创建子进程来执行,但是有一部分命令,执行的时候,没有风险,就如上面的echo命令,就只是把内容打印出来而已,没什么风险,这类命令就需要bash自己执行,我们就把这类命令叫做内建命令!

2025-10-15 22:10:50 3076 58

原创 Linux操作系统-内核中的“权力游戏”:谁决定了哪个进程坐上CPU铁王座?

而上面的完整过程就叫做linux的O(1)调度队列,有了上面所有内容的铺垫,相信大家就能理解linux中进程调度的过程:通过active指针访问queue数组来调用进程,并且将调用过的进程链接到过期队列中,在活跃队列调用完后,交换活跃队列和过期队列的内容,接着重复上面的过程。的思想,5个整数160个比特位,前面140个对应的就是queue数组中的下标,而我们要想判断queue数组的某个位置是否为空,直接判断对应的比特位是0还是1即可,0代表当前位置为空,1表示不为空,这样就能提高一定的效率。

2025-10-13 21:22:58 1584 60

原创 Linux操作系统-教科书不会讲的细节:Linux进程状态的“深度表情”

那么此时就会拿运行状态的进程开刀,虽然进程处于运行状态,但是我们都知道,除去当前在cpu上运行的,其他的进程本质还是在后面等着的,那么就和上面的阻塞状态是一样的,所以同样会把处于运行状态的进程的代码和数据交换到swap分区中来腾出空间,此时的状态就称为。是不是一下感觉问题就严重了,当然一些无关紧要的数据丢了就丢了,但是那些很重要的数据一旦丢了后果是很严重的,造成的损失是很大的,我们总不能去赌这部分数据不重要吧,并且在这个过程中系统,进程,硬盘都没有做错,做的都是份内工作。

2025-10-01 21:32:02 1549 52

原创 Linux操作系统-程序在奔跑,进程在活着:揭开计算机的“生命”奥秘

而上下文数据就和上面的你当兵去拿的档案袋一样,里面记录了截止到你当兵时的信息,所以你当完兵回来才能接着完成学业,而进行进程切换时,进程就携带着它的上下文数据,所以当再次切换到这个进程时,系统读取到它保存的上下文数据,就知道它执行到哪儿了,就可以接着执行。通过上面的例子我们可以看到,经过fork函数之后,while循环打出来的内容有不一样的,其中一个是我们最初启动的进程18176,但是我们发现还有一个进程18177启动了,并且这个子进程的父进程就是18176,同样也执行了while循环中的代码。

2025-09-27 18:25:45 1265 31

原创 Linux操作系统-基础开发工具(二)

最后的Access时间指的是文件最后被访问的时间,通过cat,less等指令都可以刷新这个时间,但是我们重复通过指令来刷新这个时间我们会发现它没有被刷新,这个时间刷新的标准有的是根据时间的间隔,也就是一段时间后才能刷新,有的是重复多次使用指令才会更改,是按次数来算。当我们使用使用cgdb调试时,进来就是上图所示的画面,通过分屏操作,上面就是我们的代码,下面就是调试的窗口,可以输入调试的相关命令,所以下面我们就以cgdb来掩饰,gdb和cgdb的命令相同的。

2025-08-04 15:41:21 1402 18

原创 Linux操作系统-基础开发工具(一)

但是我们计算机的底层还是只能识别二进制的代码,也就是0和1组成的相关数据和指令,所以我们写成的代码要想让计算机认识,就要转变成二进制的代码,而不直接从高级语言直接转化成二进制编程的原因有很多,包括难度很高等,所以就形成了现在的转换过程,先转换为汇编语言,再转成二进制的代码。上面的例子中,没有电脑的情况就是我们的程序中没有实现只有声明,所以要去网吧,也就是去动态库里面找,而我们常玩的机子就是我们常用的函数的实现,我们去网吧的过程叫做库函数跳转,回家的过程叫做库函数返回。

2025-07-29 11:02:29 1344 13

原创 Linux操作系统-为什么 root 能“为所欲为”?探寻 Linux 权限体系的上帝账户

这里就要引入sudoers这个东西,这个东西其实就相当于Linux中的白名单,只有在这个白名单中的用户才能完成sudo指令的操作,不在白名单中的用户,使用sudo时就会报上面的提示,我们只需要将当前的用户加入到sudoers文件中,就能完成相关操作,不过我们现阶段不需要知道具体是如何操作的,后面涉及到了会讲,了解一下这个知识点即可。所以这里肯定不能输管理员的密码,要输当前用户的密码,并且输过一次密码后,后面的一段时间,可能是10分钟,或者15分钟,不同的操作系统有不同的时间规定,是不需要再次输密码的。

2025-07-20 16:02:01 1653 10

原创 C++笔记-位图和布隆过滤器

所以这里我们要用到 | 进行运算,| 的效果相比我们都知道,如果我们要插入的数不存在,也就是当前的bit位为0,那么我们与此时经过左移的1进行位运算时,就会将其变为1,这点大家应该都能理解,0和1进行 | ,结果是1,1和1进行 | ,结果还是1,所以经过位运算后,只会改变对应的bit位。但是这个⽅案也有缺陷,如果⼀个值不在布隆过滤器 中,我们去删除,减减了映射位的计数,那么会影响已存在的值,也就是说,⼀个确定存在的值,可能会变成不存在,这⾥就很坑,所以设计出的reset多多少少都会有缺陷。

2025-07-03 22:11:47 1406 5

原创 C++笔记-智能指针的使用及其原理

可以看出,unique_ptr并不支持拷贝,如果拷贝就会报错,并且在这里我要提一点:unique_ptr是不支持通过=号来进行初始化的,其实上面的auto_ptr也不支持,原因就是如果用=来进行初始化的,这就相当于隐式类型转换,会产生临时对象,也就会去调用拷贝构造函数,而unique_ptr是不能拷贝的,所以不支持这种初始化。而lock的作用我们上面也说了,它会返回一个管理资源的shared_ptr,相当对多了一个shared_ptr智能指针来管理资源,相应的引用计数也会增加。

2025-06-20 13:56:32 1540 6

原创 C++笔记-当代码走向“歧路”:C++异常如何扮演程序的“救火队长”?

举个例子:我们的手机在某些地方,比如:电梯,地下室等地方信号会不好,此时我们如果给别人发消息,可能会在消息前面出现一个圆圈在转动,这种现象相信大家都遇到过,此时就是因为网络不好,抛出了异常,但不能因为信号不好就直接发不出去,因为信号不好不代表没有信号,所以底层在捕获了这种异常后,会多次尝试能否正常发送,不抛异常,如果在尝试多次后,依旧抛出异常,说明此时的网络确实没办法发送消息,在我们发送的消息面前就会出现红色感叹号。捕获异常后需要重新抛出,直接 throw;,而如果是虚函数,就可以throw e;

2025-06-16 12:49:28 798 13

原创 C++笔记-C++11(三)

可以看到我们再调整过参数顺序后,结果也发生了改变,原因就如我上面所说的_1就代表传入的第一个参数,_2代表传入的第二个参数,_1还是1,_2也还是2,但是a和b就发生了改变,a变为2,b变为1,所以结果发生了改变,不过改变参数顺序用的不多,主要还是用它来调整参数个数。function的基本应用就如上图所示,用它要注意的就是它的格式,()外的int是返回值类型,()里面的两个int就是参数类型,而正如我们上面所说,function统一了它们的类型,就相当于在它们外面套了一层壳,实际传参后调用的还是它们本身。

2025-06-13 13:31:34 1399 3

原创 C++笔记-C++11(二)

这点我在上面引用折叠部分没有讲,这里解释一下,这里的推导时C++规定的,它就是这样推导的,大家记着即可,你拿上面的例子也是如此,不过仅限于参数是右值引用,因为参数是左值引用你不管传什么类型都是左值引用,所以这里我只拿右值引用举例,而上面的右值引用例子之所以有的会报错,是因为我们显式实例化了,这里我并没有显式实例化,这里大家不要弄混了。我们来看这几个例子,相关的注释我已经写在代码旁,这里有人会疑惑:为什么传的参数是左值,推导出来的类型却是左值引用,而传右值,就是类型了?

2025-06-11 16:15:16 1211 4

原创 C++笔记-C++11(一)

上面两个函数在c++98时期这样写代价是非常大的,我们上面说过函数返回值会产生临时对象,这时就会调用拷贝构造函数来开辟新的空间在把数据一个个复制过去,而如果要将其返回值赋值给一个变量,那么又要重复上面的操作来进行,所以效率是很低的,而下面右值引用的使用场景就解决了这个问题。答案就如上图所示,和函数模板那里很相似,没有最适合的时,就用能用的,一旦有最合适的,就用最合适的,所以这里传过去的右值都会调用右值引用的函数。右值引⽤不能直接引⽤左值,但是右值引⽤可以引⽤move(左值)。

2025-06-05 18:27:39 1363 3

原创 C++笔记-O(1)的“时间魔法”:哈希表如何撕裂数据查找的时空?

开放定址法中所有的元素都放到哈希表⾥,链地址法中所有的数据不再直接存储在哈希表中,哈希表中存储⼀个指针,没有数据映射这个位置时,这个指针为空,有多个数据映射到这个位置时,我们把这些冲突的数据链接成⼀个链表,挂在哈希表这个位置下⾯,链地址法也叫做拉链法或者哈希桶。这里头插法的两行代码可能有人才开始看不懂,大家想一下,此时当前位置存储的是第一个结点的位置,因为我们是头插,所以让新创建的结点的next指向目前的第一个结点,再让当前位置存的地址换成我们新创建的结点的位置,这样是不是就顺理成章完成了头插。

2025-05-26 17:48:39 889 7

原创 C++笔记-封装红黑树实现set和map

底层为了解决这个问题也弄了和list一样的哨兵位header,并且它和根结点的_parent为对方,而在处理我们上面的代码时,会先判断是否在header这个位置,如果在的话就通过header的right直接找到整棵树的最右结点,它的left就是最左结点,可能与人觉得这样挺方便的。按照我们上面的思路,从图中可以看出50上面没有孩子是父亲左的祖先,当前子树没有我要找的祖先,那么就要一直想上找,直到最后cur走到根结点,parent走到nullptr就停止了,那么此时50下面要访问的就是nullptr。

2025-05-23 17:11:56 1353 3

原创 C++笔记-红与黑的博弈:一棵二叉树的“自律”与“平衡”之道

c为红,p为红,g为⿊,u不存在或者u存在且为⿊,u不存在,则c⼀定是新增结点,u存在且为⿊,则 c⼀定不是新增,c之前是⿊⾊的,是在c的⼦树中插⼊,符合情况1,变⾊将c从⿊⾊变成红⾊,更新上来的。c为红,p为红,g为⿊,u不存在或者u存在且为⿊,u不存在,则c⼀定是新增结点,u存在且为⿊,则 c⼀定不是新增,c之前是⿊⾊的,是在c的⼦树中插⼊,符合情况1,变⾊将c从⿊⾊变成红⾊,更新上来的。如果是⾮空树插⼊,新增结点必须红⾊结点,因为⾮空树插⼊,新增⿊⾊结点就破坏了规则4,规则4是很难维护的。

2025-05-18 18:07:12 1618 11

原创 C++笔记-AVL树(包括单旋和双旋等)

3.更新后parent的平衡因子等于2或-2,更新前更新中parent的平衡因子变化为1->2或者-1->-2,说明更新前parent子树一边高一边低,新增的插入结点在高的那边,parent所在的子树高的那边更高了,破坏了平衡,parent所在的子树不符合平衡要求,需要旋转处理,旋转的目标有两个:1、把 parent子树旋转平衡。0不是更好的平衡吗?在a子树中插入一个新结点,导致a子树的高度从h变成h+1,不断向上更新平衡因子,导致10的平衡因子从-1变成-2,10为根的树左右高度差超过1,违反平衡规则。

2025-05-14 18:05:30 1181 1

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除