📜  资质| Wipro模拟测试|问题23(1)

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

资质 | Wipro模拟测试 | 问题23

这个问题是Wipro模拟测试中的一个问题,旨在测试程序员对于二叉搜索树(Binary Search Tree)的深入理解与掌握程度。

问题描述

给定一颗二叉搜索树(BST)和值k,给定一些操作(Insert,Delete,Search)的序列,其中有些操作可能触发了平衡因子的调整。请在给定的操作序列中,找到当k被首次Search到时树的平衡因子的最大值。

解决方案

这个问题的解决方案需要你对BST的数据结构有深入的了解。BST是一种特殊的二叉树,它的每个节点都有两个子节点,并且满足左子节点的值小于该节点的值,右子节点的值大于该节点的值。这个性质保证了我们可以利用BST进行快速地Search、Insert和Delete操作。

对于这道题目,我们需要对每一个支持平衡调整的BST操作,即Insert、Delete,进行扩展,记录它们对于平衡因子的影响。同时,在进行这些操作的同时,我们需要对搜索时经过的每一个节点,统计它们的平衡因子,最终找到k被首次搜索到的时候树的平衡因子的最大值。

代码实现
class TreeNode:
    def __init__(self, val):
        self.val = val
        self.left = None
        self.right = None
        self.height = 1

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

    def insert(self, root, key):
        if not root:
            return TreeNode(key)

        if key < root.val:
            root.left = self.insert(root.left, key)
        else:
            root.right = self.insert(root.right, key)

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

        balance = self.get_balance(root)

        if balance > 1 and key < root.left.val:
            return self.right_rotate(root)

        if balance < -1 and key > root.right.val:
            return self.left_rotate(root)

        if balance > 1 and key > root.left.val:
            root.left = self.left_rotate(root.left)
            return self.right_rotate(root)

        if balance < -1 and key < root.right.val:
            root.right = self.right_rotate(root.right)
            return self.left_rotate(root)

        return root

    def delete(self, root, key):
        if not root:
            return root

        if key < root.val:
            root.left = self.delete(root.left, key)

        elif key > root.val:
            root.right = self.delete(root.right, key)

        else:
            if root.left is None:
                temp = root.right
                root = None
                return temp

            elif root.right is None:
                temp = root.left
                root = None
                return temp

            temp = self.get_min_value_node(root.right)
            root.val = temp.val
            root.right = self.delete(root.right, temp.val)

        if root is None:
            return root

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

        balance = self.get_balance(root)

        if balance > 1 and self.get_balance(root.left) >= 0:
            return self.right_rotate(root)

        if balance < -1 and self.get_balance(root.right) <= 0:
            return self.left_rotate(root)

        if balance > 1 and self.get_balance(root.left) < 0:
            root.left = self.left_rotate(root.left)
            return self.right_rotate(root)

        if balance < -1 and self.get_balance(root.right) > 0:
            root.right = self.right_rotate(root.right)
            return self.left_rotate(root)

        return root

    def search(self, root, key):
        if not root:
            return None

        if root.val == key:
            return root

        if root.val < key:
            return self.search(root.right, key)

        return self.search(root.left, key)

    def get_height(self, root):
        if not root:
            return 0

        return root.height

    def get_balance(self, root):
        if not root:
            return 0

        return self.get_height(root.left) - self.get_height(root.right)

    def left_rotate(self, z):
        y = z.right
        T2 = y.left
        y.left = z
        z.right = T2
        z.height = 1 + max(self.get_height(z.left), self.get_height(z.right))
        y.height = 1 + max(self.get_height(y.left), self.get_height(y.right))
        return y

    def right_rotate(self, z):
        y = z.left
        T3 = y.right
        y.right = z
        z.left = T3
        z.height = 1 + max(self.get_height(z.left), self.get_height(z.right))
        y.height = 1 + max(self.get_height(y.left), self.get_height(y.right))
        return y

    def get_min_value_node(self, root):
        if root is None or root.left is None:
            return root

        return self.get_min_value_node(root.left)

    def bfs(self, root, k):
        if not root:
            return

        queue = []
        queue.append(root)
        ans = 0

        while queue:
            node = queue.pop(0)

            if node.val == k:
                ans = max(ans, abs(self.get_balance(node)))

            if node.left:
                queue.append(node.left)

            if node.right:
                queue.append(node.right)

        return ans

这里我们使用了Python实现的bst中的代码,实现了bst的基本操作,同时扩展了insert、delete、search考虑平衡因子的调整。在最后的bfs中,我们利用广度优先搜索,遍历整棵树中出现的每一个节点,并统计它们的平衡因子的最大值。返回的结果就是我们需要查找的东西。