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

📅  最后修改于: 2023-12-03 15:26:08.995000             🧑  作者: Mango

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

简介

平衡二叉搜索树,简称平衡树,是一种特殊的二叉搜索树,具有自平衡的功能。它的左右子树高度差不超过1,从而保证了树的平衡性,使得插入、删除、查找等操作的时间复杂度都能达到 O(log n)。

平衡树有多种实现方式,包括AVL树、红黑树、Treap树等。其中,AVL树是最早被发明出的平衡树之一,也是最基础的一种。

问题 5

问题描述:实现一个基于AVL树的Map结构,要求支持增、删、改、查等基本操作,并且保证操作的时间复杂度都是 O(log n)。

实现思路

AVL树本身就是一种二叉搜索树,因此我们可以在其基础上实现Map结构。每个节点的键值对可以存储在节点自身中,而不必使用额外的链表结构。

具体来说,我们需要实现以下几个操作:

  • 插入元素:从根节点开始遍历树,找到合适的插入位置,并插入节点。如果在插入节点后破坏了树的平衡性,则需通过旋转操作重新平衡。
  • 删除元素:从根节点开始遍历树,找到要删除的节点,并删除。如果在删除节点后破坏了树的平衡性,则需通过旋转操作重新平衡。
  • 查找元素:从根节点开始遍历树,根据键值进行比较,找到对应的节点。
  • 修改元素:先通过查找找到要修改的节点,然后直接修改其值即可。

AVL树的旋转操作包括左旋和右旋。左旋是将一个节点的右子树取代原来的子树,同时原来的子树变为新子树的左子树,而右旋则相反。

代码实现

以下是基于AVL树的Map结构的代码实现(使用Python语言):

class AVLNode:

    def __init__(self, key, value):
        self.key = key
        self.value = value
        self.left = None
        self.right = None
        self.height = 1

class AVLMap:

    def __init__(self):
        self.root = None

    def _height(self, node):
        if node is None:
            return 0
        return node.height

    def _balance_factor(self, node):
        if node is None:
            return 0
        return self._height(node.left) - self._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._height(y.left), self._height(y.right))
        x.height = 1 + max(self._height(x.left), self._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._height(x.left), self._height(x.right))
        y.height = 1 + max(self._height(y.left), self._height(y.right))

        return y

    def _insert(self, node, key, value):
        if node is None:
            return AVLNode(key, value)
        
        if key < node.key:
            node.left = self._insert(node.left, key, value)
        elif key > node.key:
            node.right = self._insert(node.right, key, value)
        else:
            node.value = value

        node.height = 1 + max(self._height(node.left), self._height(node.right))
        balance_factor = self._balance_factor(node)

        if balance_factor > 1 and key < node.left.key:
            return self._right_rotate(node)

        if balance_factor < -1 and key > node.right.key:
            return self._left_rotate(node)

        if balance_factor > 1 and key > node.left.key:
            node.left = self._left_rotate(node.left)
            return self._right_rotate(node)

        if balance_factor < -1 and key < node.right.key:
            node.right = self._right_rotate(node.right)
            return self._left_rotate(node)

        return node

    def insert(self, key, value):
        self.root = self._insert(self.root, key, value)

    def _get_min_node(self, node):
        while node.left is not None:
            node = node.left
        return node

    def _delete(self, node, key):
        if node is None:
            return None

        if key < node.key:
            node.left = self._delete(node.left, key)
        elif key > node.key:
            node.right = self._delete(node.right, key)
        else:
            if node.left is None:
                temp = node.right
                node = None
                return temp
            elif node.right is None:
                temp = node.left
                node = None
                return temp

            temp = self._get_min_node(node.right)

            node.key = temp.key
            node.value = temp.value

            node.right = self._delete(node.right, temp.key)

        if node is None:
            return None

        node.height = 1 + max(self._height(node.left), self._height(node.right))
        balance_factor = self._balance_factor(node)

        if balance_factor > 1 and self._balance_factor(node.left) >= 0:
            return self._right_rotate(node)

        if balance_factor < -1 and self._balance_factor(node.right) <= 0:
            return self._left_rotate(node)

        if balance_factor > 1 and self._balance_factor(node.left) < 0:
            node.left = self._left_rotate(node.left)
            return self._right_rotate(node)

        if balance_factor < -1 and self._balance_factor(node.right) > 0:
            node.right = self._right_rotate(node.right)
            return self._left_rotate(node)

        return node

    def delete(self, key):
        self.root = self._delete(self.root, key)

    def _get(self, node, key):
        if node is None:
            return None
        
        if key < node.key:
            return self._get(node.left, key)
        elif key > node.key:
            return self._get(node.right, key)
        else:
            return node.value

    def get(self, key):
        return self._get(self.root, key)

    def _inorder(self, node):
        if node is None:
            return
        self._inorder(node.left)
        print(node.key, node.value)
        self._inorder(node.right)

    def inorder(self):
        self._inorder(self.root)
总结

AVL树作为一种自平衡二叉搜索树,能够保证插入、删除、查找等操作的时间复杂度都是 O(log n)。实现一个基于AVL树的Map结构并不难,只需要理解AVL树的平衡性、旋转操作和基本二叉搜索树操作即可。