红黑树的插入

一 概述

根据红黑树对二叉搜索树的一种平衡策略,保证当前结点比自己的父结点小(当前结点为父结点的左结点)或者保证当前结点比自己的父结点大(当前结点为父结点的右结点)。

二 红黑树的插入

红黑树的插入操作可以理解为以下几部分工作:

  1. 查找插入的位置。
  2. 查找到需要插入的位置之后进行插入。
  3. 把数据插入到目标位置之后然后实现自平衡。

红黑树插入操作的实际步骤:

  1. 从根节点开始查找。
  2. 如果根节点为空,则将插入的结点作为根节点,插入操作完成。
  3. 如果根节点不为空,将根节点作为当前节点,继续搜索下一个当前节点,如果当前结点为空,则返回当前结点的父结点,插入操作完成。
  4. 如果当前结点的key等于所查找的key,那么将该key所在结点就是插入结点,更新结点的值,插入操作完成。
  5. 如果当前结点的key大于所查找的key,那么将当前结点的左子结点设置为当前结点,并重复步骤4。
  6. 如果当前结点的key小于所查找到key,那么将当前结点的右子结点设置为当前结点,并重复步骤4。

上述内容让我们成功的完成了红黑树插入位置查询的操作,可是红黑树种的每个节点都是有颜色的,其实插入颜色应该是红色,因为红色节点的父节点为黑色黑色节点才能够保证红黑树的平衡。当插入的节点为黑色节点的时候无法满足红黑树的性质,即对于红黑树中的每个结点,从该结点到其所有后代叶子结点的简单路径上,均包含相同数目的黑色结点。

三 红黑树的插入场景

重要插入场景分析

场景二:当插入节点的可以已经存在的时候,说明该红黑树已经是平衡状态,因为红黑树总是保持平衡状态。但是插入后更新值的同时会将插入节点的颜色设置为该位置新插入节点的颜色。

场景三:因为插入节点的父亲节点为黑节点,插入的节点为红节点,所以不会破坏红黑树的平衡,可以直接插入。

注意:上述场景均为先找到插入点,将插入节点插入后根据红黑树的性质对红黑树进行平衡状态分析,并进行相应的左旋,右旋操作(红黑树在插入节点前本来就是平衡状态,所以在插入后重新使其平衡)。

红黑树是一种自平衡的二叉搜索树,其插入操作不仅涉及常规二叉搜索树插入逻辑,还需要通过一系列的旋转和颜色调整来维持红黑树的五条基本性质。插入操作的实现原理主要包括以下几个方面: ### 插入操作的基本流程 红黑树插入操作首先按照二叉搜索树的规则将新节点插入到合适的位置。新插入的节点默认被标记为红色,这是因为插入红色节点不会破坏红黑树的第四条性质(从任意节点到其所有叶子节点的简单路径上包含相同数量的黑色节点)[^4]。然而,插入红色节点可能会违反第三条性质(如果一个节点是红色的,则它的两个子节点必须是黑色的)[^4],因此需要通过一系列调整来修复树的性质。 ### 插入后的调整 插入新节点后,如果新节点的父节点是黑色,则无需进一步调整。但如果新节点的父节点是红色,则会违反红黑树的第三条性质,此时需要通过以下三种情况进行调整: 1. **叔叔节点为红色**:在这种情况下,父节点和叔叔节点都为红色,祖父节点为黑色。此时将父节点和叔叔节点染为黑色,祖父节点染为红色,并将当前节点设为祖父节点,继续向上调整。 2. **叔叔节点为黑色且当前节点是父节点的右子节点**:此时需要先对父节点进行左旋操作,使问题转化为第三种情况。 3. **叔叔节点为黑色且当前节点是父节点的左子节点**:将父节点染为黑色,祖父节点染为红色,并对祖父节点进行右旋操作。 通过这些调整,可以确保红黑树的性质得以维持,同时保持树的近似平衡。 ### 算法实现步骤 以下是红黑树插入操作的算法实现步骤: 1. **查找插入位置**:根据二叉搜索树的规则,找到新节点应该插入的位置。 2. **插入新节点**:将新节点插入到合适的位置,并将其颜色标记为红色。 3. **修复红黑树性质**: - 如果新节点的父节点是黑色,则无需进一步操作。 - 如果新节点的父节点是红色,则需要通过上述三种情况进行调整,以恢复红黑树的性质。 ### 代码示例 以下是一个简化的红黑树插入操作的Python代码示例: ```python class Node: def __init__(self, value): self.value = value self.left = None self.right = None self.parent = None self.color = 'Red' # 新节点默认为红色 class RedBlackTree: def __init__(self): self.root = None def insert(self, value): new_node = Node(value) if self.root is None: self.root = new_node self.root.color = 'Black' return current = self.root parent = None while current: parent = current if value < current.value: current = current.left else: current = current.right new_node.parent = parent if value < parent.value: parent.left = new_node else: parent.right = new_node self.fix_insert(new_node) def fix_insert(self, node): while node.parent and node.parent.color == 'Red': grandparent = node.parent.parent if grandparent is None: break uncle = None if node.parent == grandparent.left: uncle = grandparent.right else: uncle = grandparent.left if uncle and uncle.color == 'Red': # Case 1: Uncle is Red grandparent.color = 'Red' node.parent.color = 'Black' uncle.color = 'Black' node = grandparent else: # Case 2 & 3: Uncle is Black if node.parent == grandparent.left: if node == node.parent.right: # Case 2: Left-Right case self.left_rotate(node.parent) node = node.left # Case 3: Left-Left case self.right_rotate(grandparent) node.parent.color = 'Black' grandparent.color = 'Red' else: if node == node.parent.left: # Case 2: Right-Left case self.right_rotate(node.parent) node = node.right # Case 3: Right-Right case self.left_rotate(grandparent) node.parent.color = 'Black' grandparent.color = 'Red' self.root.color = 'Black' def left_rotate(self, node): right_child = node.right node.right = right_child.left if right_child.left: right_child.left.parent = node right_child.parent = node.parent if not node.parent: self.root = right_child elif node == node.parent.left: node.parent.left = right_child else: node.parent.right = right_child right_child.left = node node.parent = right_child def right_rotate(self, node): left_child = node.left node.left = left_child.right if left_child.right: left_child.right.parent = node left_child.parent = node.parent if not node.parent: self.root = left_child elif node == node.parent.right: node.parent.right = left_child else: node.parent.left = left_child left_child.right = node node.parent = left_child ``` ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值