📜  平衡二叉树(1)

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

平衡二叉树

介绍

平衡二叉树是一种特殊的二叉树,在其中每个节点的左右子树的高度差最多为1。这个高度差被称为平衡因子。

平衡二叉树可以保持在O(logn)的时间内进行搜索、插入和删除操作。这使它在某些应用中比其他数据结构更有用。

在平衡二叉树中,左子树的所有节点都比当前节点小,右子树的所有节点都比当前节点大。因为每个节点的子树都具有平衡性,所以整个树都具有平衡性。

平衡二叉树的适用场景包括需要高效插入、删除和搜索的任何场景。它通常被用来构建自平衡的数据结构,例如红黑树和AVL树。

实现

平衡二叉树常见的实现方式有AVL树、Red-Black树等。

AVL树在每个节点中存储平衡因子,以确保树的平衡。每次插入或删除后,需要通过旋转操作来重新平衡。

Red-Black树是使用颜色标记节点的平衡二叉树,每个节点将被标记为红或黑。这个标记是通过对树进行旋转和颜色反转来保持平衡的。

以下是一个用Python实现的平衡二叉树:

class Node:
    def __init__(self, value):
        self.value = value
        self.left_child = None
        self.right_child = None
        self.height = 1

class AVLTree:
    def __init__(self):
        self.root = None

    def insert(self, value):
        self.root = self.insert_node(self.root, value)

    def insert_node(self, node, value):
        if not node:
            return Node(value)
        elif value < node.value:
            node.left_child = self.insert_node(node.left_child, value)
        else:
            node.right_child = self.insert_node(node.right_child, value)

        node.height = max(self.get_height(node.left_child), self.get_height(node.right_child)) + 1
        balance_factor = self.get_balance_factor(node)

        if balance_factor > 1 and value < node.left_child.value:
            return self.rotate_right(node)
        elif balance_factor < -1 and value > node.right_child.value:
            return self.rotate_left(node)
        elif balance_factor > 1 and value > node.left_child.value:
            node.left_child = self.rotate_left(node.left_child)
            return self.rotate_right(node)
        elif balance_factor < -1 and value < node.right_child.value:
            node.right_child = self.rotate_right(node.right_child)
            return self.rotate_left(node)

        return node

    def delete(self, value):
        self.root = self.delete_node(self.root, value)

    def delete_node(self, node, value):
        if not node:
            return node
        elif value < node.value:
            node.left_child = self.delete_node(node.left_child, value)
        elif value > node.value:
            node.right_child = self.delete_node(node.right_child, value)
        else:
            if node.left_child is None:
                temp = node.right_child
                node = None
                return temp
            elif node.right_child is None:
                temp = node.left_child
                node = None
                return temp
            temp = self.get_predecessor(node.left_child)
            node.value = temp.value
            node.left_child = self.delete_node(node.left_child, temp.value)

        if node is None:
            return node

        node.height = max(self.get_height(node.left_child), self.get_height(node.right_child)) + 1
        balance_factor = self.get_balance_factor(node)

        if balance_factor > 1 and self.get_balance_factor(node.left_child) >= 0:
            return self.rotate_right(node)
        elif balance_factor < -1 and self.get_balance_factor(node.right_child) <= 0:
            return self.rotate_left(node)
        elif balance_factor > 1 and self.get_balance_factor(node.left_child) < 0:
            node.left_child = self.rotate_left(node.left_child)
            return self.rotate_right(node)
        elif balance_factor < -1 and self.get_balance_factor(node.right_child) > 0:
            node.right_child = self.rotate_right(node.right_child)
            return self.rotate_left(node)

        return node

    def get_predecessor(self, node):
        if node.right_child:
            return self.get_predecessor(node.right_child)
        return node

    def get_height(self, node):
        if not node:
            return 0
        return node.height

    def get_balance_factor(self, node):
        if not node:
            return 0
        return self.get_height(node.left_child) - self.get_height(node.right_child)

    def rotate_right(self, z):
        y = z.left_child
        T3 = y.right_child

        y.right_child = z
        z.left_child = T3

        z.height = max(self.get_height(z.left_child), self.get_height(z.right_child)) + 1
        y.height = max(self.get_height(y.left_child), self.get_height(y.right_child)) + 1

        return y

    def rotate_left(self, z):
        y = z.right_child
        T2 = y.left_child

        y.left_child = z
        z.right_child = T2

        z.height = max(self.get_height(z.left_child), self.get_height(z.right_child)) + 1
        y.height = max(self.get_height(y.left_child), self.get_height(y.right_child)) + 1

        return y
总结

平衡二叉树是一种非常有用的数据结构,可以在O(logn)的时间内进行搜索、插入和删除操作。它通常被用来构建自平衡的数据结构,例如红黑树和AVL树。

平衡二叉树的实现可以采用不同的方式,例如AVL树、Red-Black树等。在实现中,需要通过旋转操作和颜色标记节点等方式来保持树的平衡,并且需要进行递归操作来处理子树的变化。