厘清红黑层

embedded/2024/11/13 3:47:17/

落红不是无情物

  • 接前面
    • 红黑树转2-3-4树——雨后春笋
    • 《算法技术手册》
    • 排序——万亿数量级
  • 流量第一的图
    • 反向构造
    • 定制代码
      • 打印输出
      • 红一层黑一层
    • 真实面目
    • 加一减一插入
  • 化作春泥更护花
    • 实验
      • 计数代码
      • 测试代码
    • 少于一半
    • 黑一层红一层
      • 打印看看
  • 后话

接前面

红黑树的插入——层层历历在目想分析一下红黑树是不是红一层黑一层的。直觉告诉我红的少很多。

红黑树转2-3-4树——雨后春笋

里面0到49五十个数顺序插入构造的红黑树里只有5个红色结点。

《算法技术手册》

影印版,全英文的。从那里第一次了解了红黑树,里面说如果编码成功的话,会看到红一层黑一层的。英文是什么不记得了,也可能是我理解错了。里面学到了好多东西。

排序——万亿数量级

文章里的中值排序和点数排序都是从这本书里看到的。

流量第一的图

在这里插入图片描述
这张图也特意是黑一层红一层的。

反向构造

使用最佳二叉排序树里的方法构造。

a=[55,38,80,25,46,76,88,17,33,50,72]
B=f(sorted(a))
def breadth_fisrt_level_traversal(node):if node is None: returntemp = []temp.append(node)while temp:q=temp.pop(0)#栈先进后出print(f"({q.d})", end=" ")if q.l:temp.append(q.l)if q.r:temp.append(q.r)    
breadth_fisrt_level_traversal(B)
(50) (33) (76) (25) (46) (72) (88) (17) (38) (55) (80) 

从上面的层序输出看,它不是最佳二叉排序树。

定制代码

python">class rbtnode:'''红黑树的结点类型'''def __init__(self, val):self.val = valself.left = Noneself.right = None#self.parent = Noneself.color = "BLACK"
class rbt:def __init__(self, l):self.root = rbtnode(l[0])#第一个做根for d in l[1:]: self.i(d)#后面依次插入def search(self, n, p, d):'''search d in bstArgument:n:current nodep:parent noded:dataReturn:False/True: bool is d in bstn:current nodep:parent node'''if not n: return False, n, pif d == n.val: return True, n, pif d < n.val:return self.search(n.left, n, d)else:return self.search(n.right, n, d)def i(self, d):'''insert data d '''f, _, p = self.search(self.root, self.root, d)if not f:#d isn't in the Binary Treenew = rbtnode(d)if p.color == "BLACK":new.color = "RED"if d > p.val:p.right = newelse:p.left = new

打印输出

>>> a=[55,38,80,25,46,76,88,17,33,50,72]
>>> bst=rbt(a)
>>> bst.breadth_fisrt_level_traversal(bst.root)
(55, BLACK) (38, RED) (80, RED) (25, BLACK) (46, BLACK) (76, BLACK) (88, BLACK) (17, RED) (33, RED) (50, RED) (72, RED) 

红一层黑一层

if p.color == "BLACK":new.color = "RED"

默认都是黑的,插入时父亲黑的情况改成红色。

真实面目

就在我电脑内存里面。看打印的结果跟上面的图是一样的。

加一减一插入

跟前面一篇文章一样。再插入 [56,37,81,24,47,74,89,16,34,49,73]看看会是什么样子?

>>> for k in [56,37,81,24,47,74,89,16,34,49,73]:bst.i(k)>>> bst.breadth_fisrt_level_traversal(bst.root)
(55, BLACK) (38, RED) (80, RED) (25, BLACK) (46, BLACK) (76, BLACK) (88, BLACK) (17, RED) (33, RED) (50, RED) (72, RED) (81, RED) (89, RED) (16, BLACK) (24, BLACK) (37, BLACK) (47, BLACK) (56, BLACK) (74, BLACK) (34, RED) (49, RED) (73, RED) 

也许没有人跟我这样做。不过画出来的图是红一层黑一层的好看,而且它还满足排序二叉树的要求。

化作春泥更护花

红色应该有多少呢?

实验

进行一百次一千次的测试,每次构造一千、一万个随机数据的红黑树。

计数代码

在层序打印里改造。 r e d n o d e rednode rednode是计数的全局变量,把打印改成红色就计数。

python">	rednode = 0def count_red(self, node):if node is None: returntemp = []temp.append(node)global rednodewhile temp:q=temp.pop(0)if q.color == "red":rednode += 1if q.left:temp.append(q.left)if q.right:temp.append(q.right)

测试代码

python">import random
def test():a = random.sample(range(100000),1000)rb = RBT()for v in a:rb.INSERT(v)rb.count_red(rb.root)

少于一半

测试次数都是一千次。结点总量是样本的采样数量,比如“a = random.sample(range(100000),10000)”的结点总量是一万。
两次测试间要重启Run Module,让rednode重新计数。

结点总量红结点占比
0.5179
0.48702
0.486191
0.4865256
====================== RESTART: E:\python\redblacktree.py ======================
>>> for _ in range(1000):test()
>>> rednode
5179
>>> 5179/(10*1000)
0.5179
>>> 
====================== RESTART: E:\python\redblacktree.py ======================
>>> for _ in range(1000):test()
>>> rednode
48702
>>> 48702/(100*1000)
0.48702
>>>
====================== RESTART: E:\python\redblacktree.py ======================
>>> for _ in range(1000):test()
>>> rednode
486191
>>> 486191/(1000*1000)
0.486191
>>>  
====================== RESTART: E:\python\redblacktree.py ======================
>>> for _ in range(1000):test()
>>> rednode
4865256
>>> 4865256/(10000*1000)
0.4865256
>>> 

也许书上是对的。

黑一层红一层

也应该是黑一层红一层,黑的多一点放到前面,而且根是黑色的。真的吗?

打印看看

以下是十次测试,结点数为十的情况,后面的数字是递增的红结点数量。

(60472, black) (5310, black) (64291, black) (113, black) (25891, red) (64170, black) (71600, black) (18571, black) (26362, black) (19453, red) 2
(70107, black) (60114, red) (92505, red) (28054, black) (61038, black) (91161, black) (93008, black) (37145, red) (75132, red) (97106, red) 7
(56512, black) (11459, red) (65320, red) (10400, black) (47284, black) (57514, black) (87049, black) (51745, red) (78152, red) (88423, red) 12
(63366, black) (34922, red) (94080, black) (13361, black) (58847, black) (90974, red) (95665, red) (8136, red) (29963, red) (51217, red) 18
(37487, black) (23219, red) (57105, red) (17811, black) (31715, black) (53763, black) (77264, black) (27364, red) (55293, red) (80516, red) 23
(82827, black) (69761, red) (90332, black) (19696, black) (76237, black) (87388, red) (96580, red) (2551, red) (39740, red) (77477, red) 29
(46517, black) (10928, red) (81122, red) (2240, black) (28953, black) (55190, black) (81813, black) (28901, red) (37139, red) (86003, red) 34
(60956, black) (39834, red) (82912, black) (13236, black) (53337, black) (74831, red) (88367, red) (10667, red) (23218, red) (41492, red) 40
(63483, black) (34219, red) (75273, black) (29213, black) (56584, black) (86680, red) (14370, red) (32272, red) (49871, red) (60342, red) 46
(78954, black) (31103, red) (94441, black) (21947, black) (51170, black) (92850, red) (99061, red) (17355, red) (50960, red) (70104, red) 52

看看图片的例子是(6/11=0.54545454545454545454545454545455)普适性还差一点。

后话

删除操作后也是这样吗?


http://www.ppmy.cn/embedded/136072.html

相关文章

nodejs 019: React组件 JSX基础语法规则

注&#xff1a;本文为JSX基础语法规则总结&#xff0c;除一二级标题外的大部分内容由LLM生成JSX&#xff08;JavaScript XML&#xff09;是一种语法扩展&#xff0c;主要用于 React 项目。它让我们可以在 JavaScript 中直接编写类似 HTML 的代码&#xff0c;简化了定义 UI 组件…

网络协议都有哪些?

网络协议是为计算机网络中进行数据交换而建立的规则、标准或约定的集合。以下是一些常见的网络协议&#xff1a; TCP/IP协议&#xff1a;传输控制协议/因特网互联协议&#xff0c;又名网络通讯协议&#xff0c;是Internet最基本的协议、Internet国际互联网络的基础。由网络层的…

SpringBoot在城镇保障性住房管理中的应用

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理城镇保障性住房管理系统的相关信息成为必然…

HarmonyOS开发 - 餐饮APP中多门店多窗口打开实例补充

specified启动模式为指定实例模式&#xff0c;有一些特殊场景&#xff0c;例如多门店应用中每次打开一个门店都希望能新建一个门店实例&#xff0c;而重复打开同一个门店都是同一门店实例。 此篇为餐饮APP中多门店实例的补充内容&#xff0c;以解决同一门店多次点击重复创建新窗…

2024 Rust现代实用教程 closures闭包

文章目录 一、闭包基础概念1.如何使用闭包 二、闭包获取参数byreference与byvalue1.获取外部参数2.所有权转移move 三、闭包是怎么工作的1.闭包在底层是怎么工作的&#xff1f;2.FnOnce,FnMut,Fn特质 四、闭包类型FnOnce、FnMut和Fn做函数参数的实例参考 一、闭包基础概念 闭包…

Unity Windows 2023 Release-Notes

&#x1f308;Unity Windows 2023 Release-Notes 本文信息收集来自自动搜集工具&#x1f448; 版本更新内容2023.2.13Windows: Fixed Double backslash becoming single backslash when passing a Network path as a command line argument.(UUM-55979)2023.2.9Windows: Fixed…

斗破QT编程入门系列之二:认识Qt:编写一个HelloWorld程序(四星斗师)

斗破Qt目录&#xff1a; 斗破Qt编程入门系列之前言&#xff1a;认识Qt&#xff1a;Qt的获取与安装&#xff08;四星斗师&#xff09; 斗破QT编程入门系列之一&#xff1a;认识Qt&#xff1a;初步使用&#xff08;四星斗师&#xff09; 斗破QT编程入门系列之二&#xff1a;认识…

C++【string类,模拟实现string类】

&#x1f31f;个人主页&#xff1a;落叶 &#x1f31f;当前专栏: C专栏 目录 为什么学习string类 C语言中的字符串 标准库中的string类 auto和范围for auto关键字 迭代器 范围for string类的常用接口说明和使用 1. string类对象的常见构造 2.string类对象的容量操作 3…