📜  红黑树|自顶向下插入(1)

📅  最后修改于: 2023-12-03 14:56:49.455000             🧑  作者: Mango

红黑树 | 自顶向下插入

简介

红黑树是一种自平衡的二叉查找树,保证了在最坏情况下的基本动态操作的时间复杂度为 O(log n)。其中,自顶向下插入是一种常见的红黑树的构建方法。

红黑树的性质

红黑树主要有以下五个性质:

  1. 每个节点要么是红色的,要么是黑色的。
  2. 根节点是黑色的。
  3. 每个叶子节点(NIL节点,空节点)是黑色的。
  4. 如果一个节点是红色的,则它的两个子节点都是黑色的。
  5. 对于每个节点,从该节点到其所有后代叶子节点的简单路径上,均包含相同数目的黑色节点。
自顶向下插入算法

自顶向下插入算法是红黑树中最简单的一种构建方法,其具体实现如下:

def insert(node, key):
    if node is None:
        return Node(key)
    elif key < node.key:
        node.left = insert(node.left, key)
    else:
        node.right = insert(node.right, key)

    node = balance(node)
    return node

在插入节点时,如果节点为空,则直接将其插入为新节点,并将其颜色设置为红色。否则,如果插入的节点值小于当前节点的值,则继续向当前节点的左子树中插入;否则,向当前节点的右子树中插入。

在插入完成后,通过调用 balance(node) 函数来自下而上地进行自平衡操作。其中,balance(node) 函数的实现方式有很多种,这里采用了 LLRB(左倾红黑树)的实现方式。

balance(node) 函数

balance(node) 函数用于维护节点的平衡状态,具体实现如下:

def balance(node):
    # Case 1: 当前节点的右节点为红色,左节点为空或黑色
    if is_red(node.right) and not is_red(node.left):
        node = rotate_left(node)

    # Case 2: 当前节点的左节点和左节点的左节点均为红色
    if is_red(node.left) and is_red(node.left.left):
        node = rotate_right(node)

    # Case 3: 当前节点的左节点和右节点均为红色
    if is_red(node.left) and is_red(node.right):
        flip_colors(node)

    return node

在 balance(node) 函数中,主要通过三种情况的自平衡操作来维护节点的平衡状态。具体来说:

  1. 当当前节点的右节点为红色,而左节点为空或为黑色时,需要对当前节点进行左旋操作(rotate_left(node)),以使其满足红黑树的性质。
  2. 当当前节点的左节点和左节点的左节点均为红色时,需要对当前节点进行右旋操作(rotate_right(node)),以使其满足红黑树的性质。
  3. 当当前节点的左节点和右节点均为红色时,需要进行翻转颜色(flip_colors(node))操作,以使其满足红黑树的性质。
具体实现

完整的自顶向下插入算法的实现示例代码如下:

class Node:
    def __init__(self, key):
        self.key = key
        self.left = self.right = None
        self.color = RED

RED = True
BLACK = False

def is_red(node):
    if node is None:
        return False
    return node.color == RED

def flip_colors(node):
    node.color = not node.color
    node.left.color = not node.left.color
    node.right.color = not node.right.color

def rotate_left(node):
    new_node = node.right
    node.right = new_node.left
    new_node.left = node
    new_node.color = node.color
    node.color = RED
    return new_node

def rotate_right(node):
    new_node = node.left
    node.left = new_node.right
    new_node.right = node
    new_node.color = node.color
    node.color = RED
    return new_node

def insert(node, key):
    if node is None:
        return Node(key)
    elif key < node.key:
        node.left = insert(node.left, key)
    else:
        node.right = insert(node.right, key)

    node = balance(node)
    return node

def balance(node):
    if is_red(node.right) and not is_red(node.left):
        node = rotate_left(node)

    if is_red(node.left) and is_red(node.left.left):
        node = rotate_right(node)

    if is_red(node.left) and is_red(node.right):
        flip_colors(node)

    return node
总结

自顶向下插入算法是红黑树中最简单的一种构建方法,同时也是实现较为容易的一种方法。通过合适的自平衡调整操作,该算法可以保证红黑树的平衡性和时间复杂度。