红黑视觉化

ops/2024/11/14 5:08:48/

有图有真相

不堪回首

第一篇前就想画了,没有底气只能说打印。曾经手画过,也显示了更紧凑的234B树,还盗过图。“直男”应该是女程序员给她男朋友取的,她知道他的心底压满了栈,只能直进直出;也期待着出栈的欣喜。

0到49插入的红黑树0到49插入的红黑树

略显粗糙

最美公式

log ⁡ 2 n \log_{2}{n} log2n

log ⁡ 2 n \log_{2}{n} log2n是完全二叉树的层数,其中 n n n是接点数;只有一个结点的根结点是0层。书上原话:**性质4具有 n n n个结点的完全二叉树的高度 k k k ⌊ log ⁡ 2 n ⌋ ⌊\log_{2}{n} ⌋ log2n。⌊ ⌋向下取整。**从上图可以看出,画图的代码里构造了完全二叉树,用count += 1 #计数得到公式中的 n n n,从而求出层数。再用层数计算 x , y x,y x,y坐标。

>>> import math
>>> math.log(1,2)
0.0
>>> 

2 n 2^n 2n

每层的结点数。代码 s t e p = ( 1 / 2 ) ∗ ( ( 1 / 2 ) ∗ ∗ l e v e l ) ∗ 1500 step = (1/2)*((1/2)**level) * 1500 step=(1/2)((1/2)level)1500 #用结点数计算 x x x的间隔 s t e p step step,根是 1 2 \frac{1}{2} 21的宽度,下一层就再乘以一个 1 2 \frac{1}{2} 21。x =(count - 2**level)step2 + step 便求出了x坐标。

NIL节点(空叶子节点)为黑色

红黑树性质里都有说这个NIL结点。之前以为没有用。这次画图用到了,它是画图结束的关键,红黑树远远不是完全二叉树。只要有NIL结点就还要往下画一层。endlevel = 1 #null层,添加一个变量作为最后层的标志。

准备工作

海龟可以画直线和圆,显示数字;结点类可以添加xy坐标,树类可以添加层、接点数量属性,还可以结合后根序倒推。还有很多失败的过程,要追求的是逻辑编程的简洁。

不用担心本子不够画了

python">	from turtle import *import mathdef draw(self, node):#不用担心本子不够画了if node is None: returnsetup(width=1600, height=900) #画布大小setworldcoordinates(-50, -850, 1550, 50) #50像素页眉speed("fastest")#最快temp = [] #队列先进先出temp.append(node)#入队 step = 1/2 #根结点居中 x,y = 0,0 #结点坐标count = 0 #结点计数,完全二叉树level = 0 #层数endlevel = 1 #nul层,最后层split = True #重在一起的处理while temp:q=temp.pop(0)#出队count += 1 #计数level = int(math.log(count,2)) #当前层y = 0 - 50 * level #y下降step = (1/2)**(level+1) * 1500 #x的间隔stepif count == 2**level:x = stepelse:x =(count - 2**level)*step*2 + stepif step < 10:#重在一起处理if split:goto(x-3,y)split = Falseelse:goto(x+3,y)split = Trueelse:goto(x,y)color(q.color) #着色                if q.val != -1: #nul接点不显示 write(q.val, font=("微软雅黑", 10, "normal"))color('black') #着色完恢复if q.left and q.right: #下一层temp.append(q.left)temp.append(q.right)endlevel = level + 1 #nul层,最后层要增加elif q.left:temp.append(q.left)temp.append(RBTnode(-1))endlevel = level + 1elif q.right:temp.append(q.right)temp.append(RBTnode(-1))endlevel = level + 1elif endlevel >= level:temp.append(RBTnode(-1))temp.append(RBTnode(-1))getcanvas().postscript(file="filename.ps")#保存图片

说明

  1. 在还有子结点的情况下,endlevel = level + 1表示还有一层nil.
  2. 只画一层nil,即没有子结点但endlevel >= level的时候也入队RBTnode(-1)。再一层的时候当前层level会大于没有+1的endlevel。
  3. RBTnode(-1),在空的地方添加,以构造完全二叉树。画图的时候(-1)就不显示。

只能到九层了

第八层就重叠了,还特殊处理了才行。还好,可以从任意结点开始画。

从任意结点画

从31开始画:

>>> rb.draw(rb.root.right.right)
在这里插入图片描述‘31’开始画的红黑树

观止

所见即所得


http://www.ppmy.cn/ops/132527.html

相关文章

github.com port 22

使用GitHub的443端口 22端口可能被防火墙屏蔽了&#xff0c;可以尝试连接GitHub的443端口。 查看ssh文件夹内是否存在config文件&#xff0c;没有的话创建一个 config文件内容为 Host github.comHostname ssh.github.comPort 443 保存后重新运行git操作即可

逐梦代码深林:Linux编译之舞,链接之诗——自举、动静态库的浪漫旅程

文章目录 问题引入&#xff0c;为什么要进行编译->汇编?一、详细解释编译器自举1. 从最初的二进制编程到汇编2. 第一代汇编编译器的诞生3. 编译器自举的出现&#xff1a;从汇编到更高级的编译器4. 自举的延续&#xff1a;从汇编到高级编程语言5. 为什么要进行编译器自举&am…

PDF编辑工具Adobe Acrobat DC 2023安装教程(附安装包)

Adobe Acrobat DC 2023 是 Adobe 公司推出的一款功能强大的 PDF 文档处理软件。它不仅支持创建、编辑和签署 PDF 文件&#xff0c;还提供了丰富的工具来管理和优化这些文件。以下是 Acrobat DC 2023 的一些主要特点&#xff1a; 1.PDF 创建与编辑&#xff1a;用户可以直接从多…

cv::intersectConvexConvex返回其中一个输入点集,两个点集不相交

问题&#xff1a;cv::intersectConvexConvex返回其中一个输入点集&#xff0c;但两个点集并不相交 版本&#xff1a;opencv 3.1.0 git上也有人反馈了intersectConvexConvex sometimes returning one of the input polygons in case of empty intersection #10044 是凸包嵌套判…

设计模式-构建者

构建者是一种用于创建对象时将对象的构建过程和表示分离的设计模式,适用于构造过程复杂的对象和创建需要多种变化的场景使用. 例如一个汽车是一个抽象概念,车会具体到很多种,不同的发动机,车身,轮胎等等构建一个具体的车,所以这个具体对象创建有很多种可能.因此可以使用构建者设…

VScode插件:前端每日一题

简单说下你对 HTTP2 的理解 HTTP/2 是 HTTP 协议的一个改进版本&#xff0c;旨在提升网络传输的速度和效率&#xff0c;主要改进点包括&#xff1a; 多路复用&#xff1a;允许多个请求和响应在同一个 TCP 连接中并行传输&#xff0c;避免 HTTP/1.x 的“队头阻塞”问题。 头部压…

【HarmonyOS】not supported when useNormalizedOHMUrl is not true.

【HarmonyOS】 not supported when useNormalizedOHMUrl is not true. 问题背景&#xff1a; 集成三方库编译时&#xff0c;IDE提示报错信息如下&#xff1a; hvigor ERROR: Bytecode HARs: [cashier_alipay/cashiersdk] not supported when useNormalizedOHMUrl is not true…

MySQL 数据库之库操作

文章目录 1. 什么是数据库2. 基础概念2.1 连接数据库2.2 服务器&#xff0c;数据库&#xff0c;表关系2.3 SQL分类 3. 库的操作3.1 创建&#xff0c;选择&#xff0c;查看数据库3.2 字符集和默认校验规则 3.3 操纵数据库3.3.1 数据库查看3.3.2 数据库删除3.3.3 数据库修改 4. 其…