返回

红黑树——插入时如何自平衡

后端

红黑树是一种自平衡的二叉查找树,通过引入带颜色的节点,在进行插入或删除操作时,可以保持平衡。红黑树的插入过程大致可以分为以下几个步骤:

  1. 将新节点插入到树中,并将其颜色设置为红色。
  2. 如果新节点的父节点也是红色,则需要进行旋转和变色操作来保持平衡。
  3. 旋转操作包括左旋和右旋两种,具体取决于新节点和其父节点的位置。
  4. 变色操作是将红色节点变为黑色,将黑色节点变为红色。

通过这些步骤,可以保证红黑树在插入新节点后仍然保持平衡。红黑树的平衡性对于提高查找和删除操作的效率非常重要。在平衡的红黑树中,查找和删除操作的时间复杂度为O(log n),其中n是树中的节点数。

以下是一些示例代码,展示了如何在红黑树中插入新节点并保持平衡:

def insert(tree, key):
    # 创建新节点
    new_node = Node(key)

    # 将新节点插入树中
    tree._insert(new_node)

    # 保持平衡
    tree._balance(new_node)


def _insert(self, node):
    # 将新节点插入到正确的位置
    if node.key < self.key:
        if self.left is None:
            self.left = node
            node.parent = self
        else:
            self.left._insert(node)
    else:
        if self.right is None:
            self.right = node
            node.parent = self
        else:
            self.right._insert(node)


def _balance(self, node):
    # 如果新节点是根节点,则不需要平衡
    if node == self.root:
        return

    # 如果新节点的父节点是黑色,则不需要平衡
    if node.parent.is_black:
        return

    # 如果新节点的父节点和叔叔节点都是红色,则进行重新着色
    if node.uncle and node.uncle.is_red:
        node.parent.is_black = True
        node.uncle.is_black = True
        node.grandparent.is_red = True
        self._balance(node.grandparent)
        return

    # 如果新节点是其父节点的右孩子,且其父节点是其祖父节点的左孩子,则进行左旋
    if node == node.parent.right and node.parent == node.grandparent.left:
        self._left_rotate(node.parent)

    # 如果新节点是其父节点的左孩子,且其父节点是其祖父节点的右孩子,则进行右旋
    if node == node.parent.left and node.parent == node.grandparent.right:
        self._right_rotate(node.parent)

    # 将新节点的父节点设为黑色
    node.parent.is_black = True

    # 将新节点的祖父节点设为红色
    node.grandparent.is_red = True

    # 如果新节点的父节点是其祖父节点的右孩子,则进行右旋
    if node.parent == node.grandparent.right:
        self._left_rotate(node.grandparent)
    else:
        self._right_rotate(node.grandparent)

通过这些代码,可以实现红黑树的插入操作,并保持平衡。