在二叉搜索树中查找地板和天花板

Posted

技术标签:

【中文标题】在二叉搜索树中查找地板和天花板【英文标题】:Finding the floor and the ceiling in a binary search tree 【发布时间】:2021-08-25 16:08:32 【问题描述】:

我一直在努力解决一个代码问题,我必须在二叉搜索树中找到给定数字的下限和上限。例如,给出 5,所以程序应该打印 4 代表地板,6 代表天花板(如果它们存在)。否则,它应该为每个都打印 None。

下面是一个示例代码来解释:

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

def findCeilingFloor(root_node, k, floor=None, ceil=None):
    # Fill this in.

root = Node(8) 
root.left = Node(4) 
root.right = Node(12) 

root.left.left = Node(2) 
root.left.right = Node(6) 

root.right.left = Node(10) 
root.right.right = Node(14) 

print findCeilingFloor(root, 5)
# (4, 6)

我为 findCeilingFloor 函数实现了一些代码。虽然它找到并分配了下限和上限值,但当程序返回到包含 12 作为值的节点时,它再次将下限和上限值更改为无。因此,它总是为它们返回 None 。我添加了一些打印语句来跟踪正在发生的事情。

这是我的输出:

Problem output

这是我的实现:

def findCeilingFloor(root_node, k, floor=None, ceil=None):
    # Fill this in.
    print(f"Current node value = root_node.value")
    print(f"Floor value = floor")
    print(f"Ceil value = ceil")
    print()

    if root_node.value == k - 1:
        floor = root_node.value

    if root_node.value == k + 1:
        ceil = root_node.value

    if root_node.left:
        findCeilingFloor(root_node.left, k, floor, ceil)

    if root_node.right:
        findCeilingFloor(root_node.right, k, floor, ceil)

    return floor, ceil

我不明白为什么我的代码对它们都返回 None,即使它同时找到了 floor 和 ceil 值(ceil 值没有出现在输出中,因为它在分配 ceil 之前打印,我检查它是否也找到了 ceil)。当左子树上没有节点可走时,直接到右子树,到 12,然后 floor 和 ceil 都变为 None。

【问题讨论】:

这能回答你的问题吗? Recursive function returning none in Python TL;DR:用return findCeilingFloor(root_node.left, k, floor, ceil)替换findCeilingFloor(root_node.left, k, floor, ceil) 不,实际上,在您的问题中,它可能比这稍微复杂一些。 findCeilingFloor(root_node.left, k, floor, ceil) 替换为floor = findCeilingFloor(root_node.left, k, floor, ceil),将findCeilingFloor(root_node.right, k, floor, ceil) 替换为ceil = findCeilingFloor(root_node.right, k, floor, ceil) 地板和天花板是什么意思?您的代码似乎专门寻找 k-1k+1 的值,这可以通过简单的搜索来完成。 【参考方案1】:

您的代码存在一个主要问题。

向函数传递参数并不像你想象的那样工作

看下面的代码,尝试猜测输出,然后与实际输出进行比较:

def f(x):
  g(x)
  return x

def g(x):
  x = 3

print(f(4))

那么,输出是3,还是4?自己试试。事实证明,函数g 不会修改f 的变量xg 主体中的语句 x = 3 分配了一个名为 x 的局部变量,它与 f 的不同。

修复代码

def findCeilingFloor(root_node, k):
    # Fill this in.
    print(f"Current node value = root_node.value")
    print(f"Floor value = floor")
    print(f"Ceil value = ceil")
    print()

    floor, ceil = None, None

    if root_node.value == k - 1:
        floor = root_node.value
    elif root_node.left:
        floor = findCeilingFloor(root_node.left, k, floor, ceil)

    if root_node.value == k + 1:
        ceil = root_node.value
    elif root_node.right:
        ceil = findCeilingFloor(root_node.right, k, floor, ceil)

    return floor, ceil

另一个问题:地板和天花板的含义

很可能还有另一个问题。您可能误解了“地板”和“天花板”应该是什么。你确定那些是指k-1k+1 的值吗?您正在寻找的可能是树中小于k 的最大值,对于地板,树中大于k 的最小值,用于细胞。

【讨论】:

其实我一开始也和你一样认为ceil值应该大于等于k,而floor值应该小于等于k。尽管它在作业中是这样写的,但它想要一个输出,其中我们的输出包含 4、6 个值,正如您在我分享的第一个代码中看到的那样。因为如果它想要最大值,我们应该为 ceil 返回 14,但在示例中 ceil 应该是 6,它说。 @cagri ceil 不会是“最大值”。 ceil 将是“k 以上的最小值”。因此,例如,如果树中的值为 2、4、6、7、12、14,则 ceil(5) 将为 6;但如果树中的值为 2、4、7、12、14,则 ceil(5) 将为 7。

以上是关于在二叉搜索树中查找地板和天花板的主要内容,如果未能解决你的问题,请参考以下文章

二叉搜索树

在二叉搜索树中查找中位数的错误

在二叉查找树中插入节点

c++ 在二叉搜索树中删除

使用递归 DFS 在二叉树中查找节点

在二叉搜索树中找到一个节点的父节点