📜  门| GATE CS Mock 2018 |设置 2 |第 48 题(1)

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

门| GATE CS Mock 2018 |设置 2 |第 48 题

这是一道 GATE 计算机科学模拟考试题目,考察了提交算法、理解二叉搜索树和计算树的深度的能力。在本题中,我们需要编写一个 Python 程序来计算给定二叉搜索树的深度,同时对树进行插入和删除操作。

题目描述

题目中给出了一个二叉搜索树,包含 $n$ 个节点,每个节点包含一个整数值 $x_i$($1 \leq i \leq n$)。接下来,程序需要执行以下操作:

  • 插入一个节点 $x_i$。
  • 删除一个节点 $x_i$。
  • 计算二叉搜索树的深度。

程序需要处理多组输入数据。对于每一组输入,第一行包含一个整数 $n$,表示二叉搜索树的节点数。接下来一行包含 $n$ 个整数,表示二叉搜索树的节点值。

每组输入数据的第二部分为多个操作,每个操作占两行。第一行为操作类型,要么是 insert x,要么是 delete x。第二行是操作涉及的节点值($1 \leq x \leq 10^5$)。

对于每组输入数据,需要输出二叉搜索树的深度。如果二叉树为空,那么深度为 $0$。

示例输入输出
输入
5
4 2 5 1 3
insert 6
delete 5
delete 3
insert 7
insert 8
输出
3
解题思路

二叉搜索树(Binary Search Tree,翻译成“二叉查找树”或者“二叉排序树”)是一种数据结构,在满足以下要求的条件下,左子树比右子树小或者相等:

  • 左子树中所有节点的值小于根节点的值。
  • 右子树中所有节点的值大于或者等于根节点的值。
  • 任意子树也满足上述条件。

本题中,我们需要对给定的二叉搜索树进行插入和删除操作,并计算其深度。因此,我们需要理解二叉搜索树的性质和如何进行插入和删除操作。

对于插入操作,我们可以在二叉搜索树中查找合适的位置,如果当前节点为空,那么我们就将待插入的节点插入进去。否则,如果比当前节点的值要小,那么我们就在左子树中递归地查找;如果比当前节点的值要大,那么我们就在右子树中递归地查找。

对于删除操作,我们需要分两种情况进行考虑:

  • 如果待删除节点没有子节点,那么我们可以直接删除该节点。
  • 如果待删除节点有一个子节点,那么我们可以直接用子节点替换待删除节点。
  • 如果待删除节点有两个子节点,那么我们需要在右子树中寻找最小的节点,将该节点替代待删除节点。然后删除右子树中的那个最小节点。

计算深度的方法也很简单,我们只需要从根节点开始递归计算,深度为左右子树最大深度加一即可。

代码实现

本题的 Python 代码实现如下,基于递归实现各种操作。

from typing import List

class TreeNode:
    def __init__(self, val):
        self.val = val
        self.left = None
        self.right = None

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

    def insert(self, root: TreeNode, val: int) -> TreeNode:
        if not root:
            return TreeNode(val)
        if val < root.val:
            root.left = self.insert(root.left, val)
        else:
            root.right = self.insert(root.right, val)
        return root

    def delete(self, root: TreeNode, val: int) -> TreeNode:
        if not root:
            return None
        if val < root.val:
            root.left = self.delete(root.left, val)
        elif val > root.val:
            root.right = self.delete(root.right, val)
        else:
            if not root.left and not root.right:
                return None
            if not root.left:
                return root.right
            if not root.right:
                return root.left
            min_node_val = self.find_min(root.right).val
            root.val = min_node_val
            root.right = self.delete(root.right, min_node_val)
        return root

    def find_min(self, root: TreeNode) -> TreeNode:
        while root.left:
            root = root.left
        return root

    def find_depth(self, root: TreeNode) -> int:
        if not root:
            return 0
        left_depth = self.find_depth(root.left)
        right_depth = self.find_depth(root.right)
        return max(left_depth, right_depth) + 1

class Solution:
    def calculate_depths(self, n: int, nodes: List[int], operations: List[str], values: List[int]) -> List[int]:
        res = []
        tree = BSTree()
        for i in range(n):
            tree.root = tree.insert(tree.root, nodes[i])
        for i in range(len(operations)):
            if operations[i] == 'insert':
                tree.insert(tree.root, values[i])
            else:
                tree.delete(tree.root, values[i])
            depth = tree.find_depth(tree.root)
            res.append(depth)
        return res

其中,calculate_depths 函数接受三个参数:二叉搜索树节点数 n、节点值列表 nodes、操作列表 operations 和操作涉及的节点值列表 values。实现中,我们首先将给定的节点值列表存入二叉搜索树中,然后根据操作列表逐个进行插入和删除操作,并计算每次操作之后的二叉搜索树深度。最后返回每次操作后的深度列表。

总结

到这里,我们就介绍完了这道 GATE 计算机科学模拟考试题目——门| GATE CS Mock 2018 |设置 2 |第 48 题。本题在实现时需要注意的是,需要想清楚每种操作的具体实现方法,同时注意二叉搜索树的性质和深度的计算方式。