Python3实现红黑树[上篇]

由于时间有限,这次只写了红黑树添加节点,关于节点的删除放在下一讲 https://blog.csdn.net/qq_18138105/article/details/105324025。

关于红黑树的介绍,来由,性质和定义,可以看这篇文章,本篇就不再赘述了:红黑树,超强动静图详解,简单易懂

关于红黑树,其实比较容易摸不着头脑的是“左旋”和“右旋”。

既然是旋转,那么肯定有支点和旋点,也就是以支点为轴,旋点绕支点 顺时针逆时针旋转。
那么,“左旋” 和 “右旋” 到底哪个是顺时针,哪个是逆时针呢?
在这里,旋点一定是支点的父节点,也就是说旋点的位置比支点高,因此 左旋就是逆时针旋转,右旋就是顺时针旋转!

对于旋转,分享一个口诀:

右旋: 支点占旋点原位,支点的右给旋点作为左,旋点作为支点的右,交换支点和旋点的颜色
左旋: 支点占旋点原位,支点的左给旋点作为右,旋点作为支点的左,交换支点和旋点的颜色

先借用大神的2个图。如下图所示,就是 以p为支点,g右旋的过程,看看是否符合上面的口诀呢: 经过右旋后,支点p占据旋点g的原位,支点p的右T3作为了旋点g的左,旋点g作为了p的右

再看看左旋:经过左旋后,支点p占据旋点g的原位,支点p的左T3作为了旋点g的右,旋点g作为了p的左。也是符合上面的口诀的。

以下便是python3代码实现 红黑树插入节点的过程。

# 红黑树节点
class RBN(object):def __init__(self, data):self.data = data  # 数据域self.color = 0  # 0红 1黑self.left = Noneself.right = Noneself.parent = None# 红黑树
class RBT(object):def __init__(self):self.root = None# 中序遍历def midTraverse(self, x):if x == None:returnself.midTraverse(x.left)colorStr = '黑' if x.color == 1 else '红'parentStr = '父=' + ('nil' if x.parent == None else str(x.parent.data))print(x.data, colorStr, parentStr)self.midTraverse(x.right)# 添加一个节点def add(self, x):# 如果没有根节点 作为根节点if self.root == None:self.root = xx.color = 1  # 根节点为黑色# print('添加成功', x.data)return# 寻找合适的插入位置p = self.rootwhile p != None:if x.data < p.data:if p.left == None:p.left = xx.parent = p# print('添加成功', x.data)self.addFix(x)breakp = p.leftelif x.data > p.data:if p.right == None:p.right = xx.parent = p# print('添加成功', x.data)self.addFix(x)breakp = p.rightelse:return# 调整红黑树def addFix(self, x):while True:if x == self.root:  # 如果处理到根节点了 则着色为黑x.color = 1returnp = x.parent  # 爸爸if p.color == 1 or x.color == 1:  # 自己和爸爸只要有一个是黑的 就构不成双红 则返回return# 接下来分析红爸爸情况g = p.parent  # 爷爷 红爸爸肯定有爸爸,因为红色绝不是根节点u = g.left if p == g.right else g.right  # 叔叔 叔叔可能为空节点if u != None and u.color == 0:  # 红叔叔 则着色 然后从爷爷开始向上继续调整u.color = p.color = 1  # 叔叔和爸爸都变黑色g.color = 0  # 爷爷变红色x = g  # x指向爷爷,然后继续循环continue# 接下来分析黑叔叔得情况 有四种情况 左左,左右,右左,右右if p == g.left and x == p.left:  # 左左# 以爸爸为支点右旋爷爷self.rotateRight(p)elif p == g.left and x == p.right:  # 左右# 以x为支点左旋爸爸self.rotateLeft(x)# 以x为支点右旋爷爷(上面的旋转把爷爷变成了新爸爸)self.rotateRight(x)elif p == g.right and x == p.right:  # 右右 其实就是 左左的镜像# 以爸爸为支点左旋爷爷self.rotateLeft(p)elif p == g.right and x == p.left:  # 右左 其实就是 左右的镜像# 以x为支点右旋爸爸self.rotateRight(x)# 以x为支点左旋爷爷(上面的旋转把爷爷变成了新爸爸)self.rotateLeft(x)## 关于红黑树的旋转,一直是个难搞的点# 这里我提供一个口诀:#   右旋: 支点占旋点原位,支点的右给旋点作为左,旋点作为支点的右#   左旋: 支点占旋点原位,支点的左给旋点作为右,旋点作为支点的左## 右旋 p支点def rotateRight(self, p):g = p.parent  # 支点的父节点就是旋点# 右旋gif g == self.root:  # 若g是根节点 则p升为根节点self.root = pp.parent = Noneelse:  # 若g不是根节点 那么必然存在g.parent p占据g的位置gp = g.parentp.parent = gpif g == gp.left:gp.left = pelse:gp.right = pg.left = p.rightif p.right != None:p.right.parent = gp.right = gg.parent = p# g和p颜色交换p.color, g.color = g.color, p.color# 左旋 p 支点def rotateLeft(self, p):g = p.parent  # 支点的父节点就是旋点# 左旋gif g == self.root:  # 若g是根节点 则p升为根节点self.root = pp.parent = Noneelse:  # 若g不是根节点 那么必然存在g.parent p占据g的位置gp = g.parentp.parent = gpif g == gp.left:gp.left = pelse:gp.right = pg.right = p.leftif p.left != None:p.left.parent = gp.left = gg.parent = p# g和p颜色交换p.color, g.color = g.color, p.colorif __name__ == '__main__':rbt = RBT()datas = [10, 20, 30, 15]# datas = [11, 2, 14, 1, 7, 15, 5, 8, 4]for x in datas:rbt.add(RBN(x))rbt.midTraverse(rbt.root)

关于红黑树节点的删除,请看下回分解。

Python3实现红黑树[上篇]相关推荐

  1. Python3实现红黑树[下篇]

    Python3实现红黑树[下篇] 我写的红黑树的上篇在这里:https://blog.csdn.net/qq_18138105/article/details/105190887 这是我近期看的文章 ...

  2. 红黑树的插入与验证——附图详解

    文章目录 红黑树 性质 红黑树的插入 前言 寻找插入位置 情况 1.0 情况 1.1 情况 1.2 情况 1.3 情况 2.0 情况 2.1 情况 2.2 情况 2.3 完整代码 红黑树的检验 验证代 ...

  3. 浅谈树形结构的特性和应用(上):多叉树,红黑树,堆,Trie树,B树,B+树......

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 上篇文章我们主要介绍了线性数据结构,本篇233酱带大家看看 无所不 ...

  4. 面试旧敌之红黑树(直白介绍深入理解)

    2019独角兽企业重金招聘Python工程师标准>>> 读完本文你将了解到: 什么是红黑树 黑色高度 红黑树的 5 个特性 红黑树的左旋右旋 指定节点 x 的左旋 右图转成左图 指定 ...

  5. 彻底理解面试难点之rb-tree(红黑树)续--对红黑树的插入和删除操作的一些理解!!!

    这里主要讲一下对红黑树的插入和删除操作的一些理解 对于红黑树的一些相关性质的介绍,上篇已经讲了,这里不再介绍,有需要了解的,可以翻前面的博客看看. 1.红黑树的插入操作 对于红黑树的元素插入,我们首先 ...

  6. pygraphviz的安装与红黑树可视化

    大家好,我是小小明,今天我将带大家安装pygraphviz,并通过它对红黑树这种数据结构进行可视化. pygraphviz的安装与红黑树的可视化 安装graphviz 下载地址:http://www. ...

  7. 图解:什么是红黑树?(下篇)

    点击关注上方"五分钟学算法", 设为"置顶或星标",第一时间送达干货. 转自景禹 说到红黑树的删除操作,不得不提 图解:什么是红黑树?(中篇)中所讲的红黑树的插 ...

  8. 红黑树 键值_大厂面试官:说一下JDK1.8 HashMap有哪些亮点?

    上篇我们介绍了JDK1.7版的HashMap,今天我们来讲解下JDK1.8版的HashMap. JDK1.7的实现大家看出有没有需要优化的地方? 其实一个很明显的地方就是:当 Hash 冲突严重时,在 ...

  9. Java 集合深入理解(17):HashMap 在 JDK 1.8 后新增的红黑树结构

    点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 上篇文章我们介绍了 HashMap 的主要特点和关键方法源码解读,这篇文章我们介绍 HashMap 在 JDK1.8 新增 ...

最新文章

  1. C编程,随机数,排序
  2. 二叉树题目----6 二叉树的最近公共祖先 AND 二叉树搜索树转换成排序双向链表
  3. ASIHttpRequest:创建队列、下载请求、断点续传、解压缩
  4. CMD执行命令出现NOMALY: meaningless REX prefix used以及IDEA提示Cannot run git问题解决
  5. Java 时间处理 Instant
  6. java 字节乱码_Android/Java 字节读取出现乱码问题
  7. IOS--CALayer实现,界限、透明度、位置、旋转、缩放组合动画(转)
  8. 【干货】GRU神经网络
  9. clipse和IDEA快捷键对照表
  10. Ambari 安装配置 MySql
  11. 【数学建模】CUMCM-2009B 眼科病床的合理安排 解题思路整理
  12. JAVA毕设项目民航售票管理系统(java+VUE+Mybatis+Maven+Mysql)
  13. sqlite设密工具如何使用(本人资源)
  14. 从四大造字法看文字所承载的文化_举例说明汉语汉字所承载的文化信息?
  15. python中安装decimal模块_python decimal和fractions模块
  16. 绿色债券数据集2016.01-2021.11年
  17. 将 vim 外的内容复制并粘贴到 Vim 里使用,如从windows系统复制内容到vim中使用
  18. 大概是全网最详细的Electron ipc 讲解(二)——渲染进程与渲染进程的搭桥牵线
  19. .Net C# 如何读取Excel数据内容写入数据库并通过DataGridView控件动态刷新显示
  20. 汇编语言程序设计IV-贺利坚-专题视频课程

热门文章

  1. APIGEE:用于API代理的CI / CD管道
  2. Java更快地对基元数组进行排序?
  3. 在EL表达式中引用ADF Faces组件
  4. Drools 6.5.0.Final提供
  5. JUnit 5 –下一代JUnit的初步了解
  6. 在Java中模拟求和类型的巧妙解决方法
  7. Java英雄:丹·艾伦
  8. Java:逐步读取/流式传输CSV文件
  9. 测试Spring的“会话”范围
  10. Java EE中的配置管理