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

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

数据结构 | 二叉搜索树 | 问题 8

什么是二叉搜索树?

二叉搜索树(Binary Search Tree,BST)是一种基于二叉树的数据结构。它具有以下性质:

  1. 左子树上所有节点的值均小于它的根节点的值。
  2. 右子树上所有节点的值均大于它的根节点的值。
  3. 左右子树本身也都是二叉搜索树。

因此,在搜索某个值时,可以根据这个值与当前节点的大小关系,进一步判断去左子树还是右子树搜索。

问题描述

现有一个二叉搜索树,请你实现其中的两个函数 getRandomNodeinsert

  • getRandomNode() 方法:随机返回树中的任意一个节点。
  • insert(val) 方法:插入值为 val 的节点。

请注意,同一个值不能重复插入。

解决方案
getRandomNode

为了实现随机返回一个节点,我们可以先确定树中的节点总数,然后随机生成一个在 [1, total] 范围内的随机整数 rand,接着从根节点开始,按照中序遍历的顺序访问每个节点并累加 visit 值。如果当前 visit 的值等于 rand,说明找到了对应的节点,返回即可。

下面是具体的代码实现:

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

class Solution:
    def __init__(self, root: TreeNode):
        self.root = root
        self.total = self.get_total(root)

    def getRandomNode(self) -> int:
        rand = random.randint(1, self.total)
        return self.search(self.root, rand).val

    def insert(self, val: int):
        if self.search(self.root, val):
            return

        p = self.root
        while p:
            if val < p.val:
                if not p.left:
                    p.left = TreeNode(val)
                    self.total += 1
                    return
                p = p.left
            else:
                if not p.right:
                    p.right = TreeNode(val)
                    self.total += 1
                    return
                p = p.right

    def search(self, root: TreeNode, k: int) -> TreeNode:
        if not root:
            return None

        left_sum = 0
        if root.left:
            left_sum = root.left.visit
        if left_sum + 1 == k:
            return root
        elif left_sum >= k:
            return self.search(root.left, k)
        else:
            return self.search(root.right, k - left_sum - 1)

    def get_total(self, root: TreeNode) -> int:
        if not root:
            return 0
        root.visit = self.get_total(root.left) + self.get_total(root.right) + 1
        return root.visit
insert

插入操作比较简单,直接从根节点开始往下遍历,按照二叉搜索树的规则插入即可。插入操作的时间复杂度为 $O(h)$,其中 $h$ 是树的高度。

总结

本文介绍了二叉搜索树的基本概念,并给出了解决上面问题的思路和代码实现。需要注意的是,本文实现的二叉搜索树是基于 Python 的类实现,可以根据需要自行调整实现方式。