二叉搜索树与算法实现解析

20、画出一个包含N个节点的二叉搜索树的结构草图,该树查找两个最大值需要O(N)的时间。接着,再画出一个包含N个节点的二叉搜索树的结构草图,该树查找两个最大值需要O(1)的时间。

对于需要 O(N) 时间查找两个最大值的二叉搜索树,当所有节点按升序插入时,树会退化为一个长的线性链,类似链表。此时查找最大值需要遍历到链表末尾,查找第二大值需要遍历到倒数第二个节点,时间复杂度为 O(N)。

对于需要 O(1) 时间查找两个最大值的二叉搜索树,树应是高度平衡的,且最大值在根节点的右子节点,第二大值在根节点的右子节点的左子节点,这样可以直接访问到这两个节点,时间复杂度为 O(1)。

由于无法直接绘制草图,可按上述描述自行绘制。

21、如果你想在二叉搜索树中找到第 k 小的键,一种低效的方法是遍历整个树,直到访问了 k 个节点。请在 BinaryTree 中添加一个 select(k) 函数,该函数返回从 0 到 N - 1 的第 k 小的键。为了实现高效的实现,需要扩展 BinaryNode 类,以存储一个额外的字段 N,该字段记录以该节点为根的子树中的节点数(包括该节点本身),例如,叶子节点的 N 值为 1。另外,在 BinaryTree 中添加一个配套方法 rank(key),该方法返回一个从 0 到 N - 1 的整数,该整数反映了键在排序顺序中的排名(即树中严格小于该键的键的数量)。

低效方法是遍历整个树直至访问 k 个节点。高效方法是在 BinaryTree 中添加 select(k) 函数来返回第 k 小的键,同时扩展 BinaryNode 类增加字段 N 记录以该节点为根的子树节点数。此外,在 BinaryTree 中添加 rank(key) 方法,返回键在排序顺序中的排名,即树中严格小于该键的键的数量。

22、AVL树是自平衡的。对于给定的N,由于AVL树无法像完全二叉树那样完美紧凑,能否计算出包含N个值的AVL树的最大高度?生成10000个大小为N的随机AVL树,并记录每个N对应的最大观测高度。创建一个表格,记录最大观测高度增加的情况。预测N的值,使得具有N个节点的AVL树的高度比具有N - 1个节点的AVL树的高度大1。

可以按以下步骤操作:

  1. 首先,生成 10000 个大小为 N 的随机 AVL 树,记录每个 N 对应的最大观测高度;
  2. 然后创建表格记录最大观测高度增加的情况;
  3. 最后根据记录的数据预测满足条件的 N 值。

23、完成一个 SpeakingBinaryTree 类,使其 insert(val) 操作在执行时能生成操作的英文描述。此递归操作是“自上而下”处理的,而大多数递归函数是从基本情况“自下而上”处理的。修改 _insert() 函数以返回一个元组 (node, explanation) ,其中 node 是结果节点, explanation 包含操作的详细描述。

以下是完成后的 SpeakingBinaryTree 类代码:

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

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

    def insert(self, val):
        (self.root, explanation) = self._insert(self.root, val, 'To insert `{}`,'.format(val))
        return explanation

    def _insert(self, node, val, sofar):
        if node is None:
            explanation = sofar + f' create a new node with value {val}.'
            return (BinaryNode(val), exp
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值