📜  数据结构 |平衡二叉搜索树 |问题 10(1)

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

数据结构 | 平衡二叉搜索树 | 问题 10

平衡二叉搜索树是一种能够自动调整结点的高度,以保持整个树的平衡的二叉搜索树。它结合了二叉搜索树的查找和插入操作的高效性以及自平衡的能力,使得查询和插入操作的时间复杂度为 O(log n)。

常见的平衡二叉搜索树

常见的平衡二叉搜索树有以下几种:

  • AVL 树:最早提出的一种平衡二叉搜索树,每个结点的左右子树高度差不超过 1。
  • 红黑树:近似平衡的二叉搜索树,满足以下 5 个性质:根节点为黑色;每个叶子结点为黑色;如果一个结点为红色,则它的子结点必须都是黑色的;从任意结点到其每个叶子的所有路径包含相同数目的黑色结点;空子树也被视为黑色。
  • Splay 树:不仅仅是平衡二叉搜索树,还具有自适应性,即在使用过程中如果某个结点被访问频繁,则该结点被放到根节点。
解决的问题

平衡二叉搜索树主要解决的问题是二叉搜索树中存在极端不平衡的情况。如果一棵二叉搜索树恰好是一个链表,那么查询一个结点的时间复杂度就退化为 O(n),其中 n 是结点数。而平衡二叉搜索树可以自动调整结点的高度,使得整个树始终保持平衡,从而保证查询的时间复杂度为 O(log n)。

示例代码

下面是使用 Python 实现的 AVL 树:

class Node:
    def __init__(self, val):
        self.val = val
        self.left = None
        self.right = None
        self.height = 1

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

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

    def get_bal_factor(self, node):
        if not node:
            return 0
        return self.get_height(node.left) - self.get_height(node.right)

    def right_rotate(self, y):
        x = y.left
        T2 = x.right

        x.right = y
        y.left = T2

        y.height = 1 + max(self.get_height(y.left), self.get_height(y.right))
        x.height = 1 + max(self.get_height(x.left), self.get_height(x.right))

        return x

    def left_rotate(self, x):
        y = x.right
        T2 = y.left

        y.left = x
        x.right = T2

        x.height = 1 + max(self.get_height(x.left), self.get_height(x.right))
        y.height = 1 + max(self.get_height(y.left), self.get_height(y.right))

        return y

    def insert(self, node, val):
        if not node:
            return Node(val)
        elif val < node.val:
            node.left = self.insert(node.left, val)
        else:
            node.right = self.insert(node.right, val)

        node.height = 1 + max(self.get_height(node.left), self.get_height(node.right))

        bal_factor = self.get_bal_factor(node)

        if bal_factor > 1:
            if val < node.left.val:
                return self.right_rotate(node)
            else:
                node.left = self.left_rotate(node.left)
                return self.right_rotate(node)

        if bal_factor < -1:
            if val > node.right.val:
                return self.left_rotate(node)
            else:
                node.right = self.right_rotate(node.right)
                return self.left_rotate(node)

        return node

在上面的代码中,Node 类表示 AVL 树的结点,包括结点的值、左右子结点和高度。AVL 类表示 AVL 树,包括 AVL 树的根节点和 AVL 树的操作,如获取结点的高度、获取结点的平衡因子、右旋、左旋和插入。其中,插入操作使用了递归方式实现,每次插入完结点之后,需要判断当前结点的平衡因子是否为 ±1,如果不是则进行旋转操作。右旋需要进行结点的左旋转和当前结点的右旋转两个操作,左旋同理。