数据结构之平衡树:红黑树的介绍与Python代码实现——17
红黑树的介绍与Python代码实现
红黑树的介绍
- 红黑树(Red-Black Tree)是一种平衡二叉查找树,它是一种以比较简单的方式实现的2-3查找树
红黑树基于2-3查找树的表现
- 红链接:将两个2-结点连接起来构成一个3-结点 ;
- 黑链接:则是2-3树中的普通链接。
红黑树的定义:
红黑树是含有红黑链接并满足下列条件的二叉查找树: .
- 红链接均为左链接;
- 没有任何一个结点同时和两条红链接相连;
- 该树是完美色平衡的,即任意空链接到根结点的路径上的黑链接数量相同;
红黑树的优点:
- 一颗二叉树,每一个结点只需要额外多一位空间即可实现红黑树,这一位空间通常用于存放和表示红黑结点,而这些红黑标识则可以用来使红黑树保持接近平衡的状态
- 记录每一个结点的红黑状态,只需要额外的一位空间,这使得红黑树的储存空间大小在一定程度上可以认为和无颜色标记的二叉树的储存空间大小等同,在大多数情况下,无需额外的储存成本就能储存着一位的红黑记录信息
- 红黑树不是完美的平衡二叉树,但是它的平衡状态足够让我们能很方便地进行搜寻操作,红黑树的查询、插入、删除操作时间复杂度都是O(log n)
红黑树的平衡化
为什么需要平衡化?
- 在对红黑树进行一些增删改查的操作后 ,很有可能会出现红色的右链接或者两条连续红色的链接,而这些都不满足红黑树的定义,所以我们需要对这些情况通过旋转进行修复,让红黑树保持平衡。
平衡化的方法
- 左旋
- 右旋
左旋
时机:
- 当某个结点的左子结点为黑色,右子结点为红色,此时需要左旋。
实现方式:
- 当前节点为h,它的右节点是x;
color的值是由父结点指过来的线的颜色
实现过程:
右旋
时机:
- 当某个结点的左子结点是红色,并且左子结点的左子结点也是红色,要右旋
实现方式
- 前提:当前结点为h ,它的左子结点为x ;
color的值由父结点指过来的线的颜色
实现过程:
右旋之后保持了有序性;但是红链接连接了三个结点不满足2-3树的性质,同时违背了红黑树右链接不能为红链接的要求,这个问题下面将会介绍使用颜色反转的方法来解决
平衡步骤
- 向单个2-结点中插入新键后,结果是插入到该结点的右子结点,则需要进行左旋:
将c结点替换b(使b=c),b的颜色变为红,然后让b称为c的左子节点即可完成左旋(根结点的颜色后面会有一个操作让其始终保持黑色) - 向底部的2-结点插入新键
情况同一,只是需要多一步,左旋之后,C的颜色要变为黑色(表示指向C的边为红色) - 颜色反转
当一个结点的左子结点和右子结点的color都为RED时, 也就是出现了临时的4-结点,此时只需要把左子结点和右子结点的颜色变为BLACK ,同时让当前结点的颜色变为RED即可。 - 向一棵双键树(即一个3-结点)中插入新键
可分为三种子情况
4-1. 新键大于原树中的两个键:
4-2. 新键小于原树中的两个键
4-3. 新键介于原数中两个键之间
- 根结点的颜色总是黑色
在每次放入元素的操作完成之后,将根结点的颜色变更为’Black’即可:
self.root.color = 'Black'
- 向树底部的3-结点插入新键
操作方法
- is_red(node) 判断传入的结点node是否为红色
- rotate_left(node) 将传入的结点进行左旋操作
- rotate_right(node) 将传入的结点进行右旋操作
- alter_color(node) 将传入的结点进行颜色反转操作
- put(key, val) 插入一个键为key,值为val的元素,插入之后自动按键进行排序
- get_value(key) 根据传入的键key,获取对应结点的值
Python代码实现
二叉树结点设计
class Node:def __init__(self, key, value):self.key = keyself.value = valueself.left = Noneself.right = Noneself.color = False
功能实现
class RedBlackTree:def __init__(self):self.root = Noneself.N = 0def size(self):return self.Ndef is_red(self, node):return str(node.color).lower() == 'red' if node else Falsedef rotate_left(self, node):"""Rotate left when the edge from the current node to its right child node is red"""# h is the current nodeh = node# x is the current node's right childx = node.righth.right = x.leftx.left = hx.color = h.colorh.color = 'Red'return xdef rotate_right(self, node):"""Rotate right when both the left edge and the left child's left edge are red"""h = nodex = node.lefth.left = x.rightx.right = hx.color = h.colorh.color = 'Red'return xdef alter_color(self, node):"""Alter a node's color"""node.color = 'Red'node.left.color = 'Black'node.right.color = 'Black'def put(self, key, val):"""Put an element into this tree"""def put_into(node, key, val):if not node:return Node(key, val)# Rank the orderif key < node.key: # Recursively to compare key with its left childnode.left = put_into(node.left, key, val)elif key > node.key:node.right = put_into(node.right, key, val)else: # Swap their the node.value with valnode.value = valreturn node# Rotation or alter colorif self.is_red(node.right) and not self.is_red(node.left):# Rotate leftself.rotate_left(node)if self.is_red(node.left) and self.is_red(node.left.left):# Rotate rightself.rotate_right(node)if self.is_red(node.left) and self.is_red(node.right):# Alter colorself.alter_color(node)self.N += 1return nodeself.root = put_into(self.root, key, val)self.root.color = 'Black'return self.rootdef get(self, key):"""Get a value according to the given key"""def get_value(node, key):if not node:returnif key < node.key:return get_value(node.left, key)elif key > node.key:return get_value(node.right, key)else:return node.valueval = get_value(self.root, key)return val
代码测试
if __name__ == '__main__':RBT = RedBlackTree()RBT.put(1, 'G')RBT.put(2, 'K')RBT.put(3, 'd')RBT.put(3, 'D')for i in range(1, 4):print(RBT.get(i), end=' ')print('\n', RBT.size())print(RBT.root.color)print(RBT.root.key, RBT.root.value)print(RBT.root.right.key, RBT.root.right.value)print(RBT.root.right.right.key, RBT.root.right.right.value)
测试结果
G K D 5
Black
1 G
2 K
3 D
插入的元素都按照对应的键获取到了,说明代码没有什么问题
数据结构之平衡树:红黑树的介绍与Python代码实现——17相关推荐
- 红黑树详解(一)红黑树的介绍和操作
红黑树详解(一)红黑树的介绍和操作 摘要: 在很多源码涉及到大量数据处理的时候,通常都是用红黑树这一数据结构.红黑树是一种自平衡的二叉查找树,它能在进行插入和删除操作时通过特定操作保持二叉查找树的平衡 ...
- 数据结构 - 学习笔记 - 红黑树
数据结构 - 学习笔记 - 红黑树 定义 简介 知识点 1. 结点属性 2. 前驱.后继 3. 旋转 查找 插入 父结点为黑色 父结点为红色 1. 有4种情形只需要变色(对应234树4结点) 1.1. ...
- 数据结构之「红黑树」
红黑树 红黑树(Red–black tree)是一种自平衡二叉查找树.红黑树是每个节点都带有颜色属性的二叉查找树,颜色为红色或黑色. 红黑树的特性: 1.节点要么是红色要么就是黑色,不能没有颜色. 2 ...
- 数据结构-动态查找树表与平衡二叉树 红黑树简单介绍
参考资料 数据结构(严蔚敏) 大话数据结构 百度百科 https://blog.csdn.net/lpp0900320123/article/details/39524947 https://mp.w ...
- MySQL索引数据结构二叉树、红黑树、B-Tree、B+Tree、Hash
索引:帮助MySQL高效获取数据的有序的数据结构. 假设我们有一张表table,包含Clo1和Clo2两个字段 内存地址 Clo1 Clo2 0x07 1 36 0x5A 2 20 0x7A 3 80 ...
- 高级数据结构与算法 | 红黑树(Red-Black Tree)
文章目录 红黑树 红黑树的概念 红黑树的性质 红黑树与AVL树 红黑树的实现 红黑树的节点 红黑树的插入 红黑树的查找 红黑树的验证 完整代码 红黑树 红黑树的概念 红黑树,是一种二叉搜索树,但在每个 ...
- 数据结构拾遗(1) --红黑树的设计与实现(上)
红黑树是一种自平衡的二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组(C++ STL 中的map/set).它是在1972年由Rudolf Bayer发明的,他称之为" ...
- 数据结构与算法 / 红黑树
一.定义 根节点是黑色的. 叶子节点是空的且是黑色的. 任何相邻的节点不能都为红色. 任意节点到其每个叶子节点的路径上,黑色的节点的数量相同. 二.性质 红黑树解决了 AVL 树增.删时耗时过大的问题 ...
- 父子结构查询_Java面试准备(5)之数据结构与算法——红黑树
欢迎点赞评论+关注~~~~~~~ 如上图,二叉查找树极端情况下可能会变成一个单链表,这种查询时间复杂度就变成O(n)了,红黑树在二叉查找树的基础上进行了自平衡. 1.原理分析 如上图,红黑树具有以下特 ...
最新文章
- 计算机学院大学生程序设计竞赛(2015’11)1007 油菜花王国
- AI工程师面试凭高频问题提前准备,命中率会是多少?
- 网站重启服务器有啥好处,常规服务器重启的好处和障碍
- blob转成json js_javascript – 文件API – Blob到JSON
- C++ struct实现顺序表
- select函数_SQL高级功能:窗口函数
- 复习----使用链表实现队列(先进先出)及迭代
- TP-LINK WN823N 无线驱动 ubuntu
- hive基于多列去重操作
- Linux内核分析作业 NO.2
- GCC编译器的安装教程(Windows环境)
- 机器学习算法 07 —— 朴素贝叶斯算法(拉普拉斯平滑系数、商品评论情感分析案例)
- 简单!Python+OpenCV三步去除水印
- centos 内网ip 设置_CentOS7 设置局域网固定IP
- gmail客户端设置
- win10 修改用户名
- 首先提出电子计算机存储程序的科学家,1、世界上首先实现存储程序的电子数字计算机是___C_。.doc...
- 查看电脑连接过的无线网密码
- 苹果手机时间显示invalid Date
- Google 发布 ARCore 1.0
热门文章
- 面向对象方法开发的方法
- html如何设置滑轮效果,HTML中鼠标滚轮事件onmousewheel处理
- php 计算数据偏离度,关于偏离度的测算方法
- grid autosport额外内容下载慢_清理大王app下载-清理大王v1.0安卓下载
- 计算机工作原理 公开课,《计算机的基本工作原理》公开课材料(11页)-原创力文档...
- 模板vs定制 门店小程序该如何选择?
- 开源微信管家平台——JeeWx 捷微4.0 微服务版本发布,全新架构,全新UI,提供强大的图文编辑器...
- 怎么在前台取的ViewBag中的值
- Linux CentOS7/RHEL7关闭ctrl+alt+delete功能键
- 【Maven入门教程】Maven的基本概念