【问题标题】:In-order traversal of two binary trees to compare which one is bigger按顺序遍历两棵二叉树以比较哪一棵更大
【发布时间】:2021-01-14 06:30:34
【问题描述】:

我正在尝试找到一种方法来比较二叉树中的节点,以查看一棵树的节点是否比另一棵“大”。我想比较它们的方式是比较最左边的节点、根节点,然后是最右边的节点。我认为最好的方法是使用递归执行有序遍历并以这种方式比较节点。

但是,在递归调用该函数时,我很难找到一种方法让它返回正确答案。递归确实有一种让我感到困惑并忘记程序正在做什么的方式。我有以下内容:

function binaryTreeComparison(node1, node2) {

        if node1 and node2 is null
            return 0
        
        if node1 is not null, but node2 is null
            return 1
        
        if node1 is null, but node2 is not null
            return -1
        
        else {
            binaryTreeComparison(node1.getLeftChild(), node2.getLeftChild())

            if node1 > node 2 
                return 1
            
            else if node1 = node 2
                return 0
            
            else if node1 < node2 
                return -1
            
            binaryTreeComparison(node1.getRightChild(), node2.getRightChild());
        }
        return 0
    }

对我尝试伪代码表示歉意。试图创建一个最小的、可重复的示例。发生了什么,而不是中断并返回不同的节点的第一个实例,而是我认为它返回“递归堆的顶部”,我不知道有什么方法可以解决这个问题。我确信这与我没有做类似return binaryTreeComparison(node1.getLeftChild(), node2.getLeftChild()); 的事情有关。例如,如果我们有两棵像这样的二叉树:

     4           4
    / \         / \
   2   5       6   5

然后它应该在访问左下角节点后返回 -1,因为 6 > 2。相反,它返回 0,因为它在树的顶部比较 4 = 4。不同高度的树木的另一个例子是:

     4           4
    / \         / \
   6   5       6   5
  /
 3

这里左边的树会大于右边的树,因此返回 1。谢谢你的帮助。我搜索了许多其他地方以寻求帮助,但我无法弄清楚。

【问题讨论】:

  • 两棵二叉树的结构一样吗?换句话说,它们是否具有相同数量的节点、相同数量的叶节点、相同数量的级别和相同数量的分支?您问题中的图表显示了两个具有相同结构的二叉树。
  • 不是先比较值,而是推迟比较,直到比较子项。您需要确定如果一侧有子节点而另一侧没有子节点意味着什么......我也不确定我是否理解您的示例 - 假设顶部有 4 和排序树,左边孩子应该小于 4 岁。
  • @Abra 这些树可能有不同的结构。但是,它们仍然被归类为二叉树。
  • 那么,如果一棵树的层级比另一棵树多,你比较的是哪些节点?也许edit您的问题,并发布两个具有不同级别的二叉树的示例以及您希望如何比较它们。
  • @Gus 例如,可以给定的树不是最大堆或最小堆,因此子级增加或减少之间没有真正的关系。它们只是随机值。你会如何首先比较孩子?我做了 if 语句的第一部分,为递归提供了一种“退出条件”,以便它在到达叶子时停止。

标签: java recursion binary-tree nodes inorder


【解决方案1】:

小记,您的代码不是真正可重现的,因为它是伪代码,所以我不能 100% 确定您的问题是否正确,因为我不知道这个问题是否真的存在于您的代码中。以您正在使用的语言实际查看您的真实代码,而不需要与问题无关的内容,这将很有用。

但是,我已经实现了您在散文和伪代码中描述的内容,并且我相信我正在经历您的行为。我仍然不是 100% 确定我完全理解您想要的比较,但我希望这是有道理的:

基本上,您的结构是正确的。我认为您在考虑从左侧向下遍历的问题。这似乎是人们在学习递归时经常遇到的问题。我在学习的时候经常犯这个问题。相反,通过递归,您可以将事情缩小到最基本的情况,并让递归处理应用它们。在这种情况下,我认为您有很多案例:

  1. node1 为空,node2 为空
  2. node1 为空,node2 不为空
  3. node1 不为空,node2 为空
  4. node1 的左孩子!= node2 的左孩子
  5. node1 的值!= node2 的值
  6. node1 的右孩子!= node2 的右孩子
  7. node1 == node2

我不确切知道您的代码是什么样的。在您的伪代码中,有两个主要问题。我假设第一个问题实际上不在您的代码中,即当您递归时,您没有检查并返回结果。如果结果 != 0,您只想返回结果。所以,而不是:

binaryTreeComparison(node1.getLeftChild(), node2.getLeftChild())

你想要

leftResult = binaryTreeComparison(node1.getLeftChild(), node2.getLeftChild())
if (leftResult != 0) return leftResult

您的代码的关键问题是您重复了条件 (7)。这解释了您遇到的行为:

我认为不是中断并返回不同节点的第一个实例,而是返回“递归堆的顶部”,我不知道有什么方法可以解决这个问题

你实际上只是想删除它,因为一旦你检查了 node1.value node2.value,你知道 node1.value == node2.value。但是,你必须等到你检查右边之前返回0,否则你将永远忽略右边的孩子。相信底部的return 0 会起作用:-)

这是 Python 中的工作代码:

from dataclasses import dataclass

@dataclass
class Tree:
    value: int
    left: 'Tree' = None
    right: 'Tree' = None

def compare(node1: Tree, node2: Tree) -> int:
    if node1 is None and node2 is None:
        return 0
    if node1 is not None and node2 is None:
        return 1
    if node1 is None and node2 is not None:
        return -1

    left = compare(node1.left, node2.left)
    if left != 0:
        return left

    if node1.value > node2.value:
        return 1
    # This is your bug
    # if node1.value == node2.value:
    #     return 0
    if node1.value < node2.value:
        return -1

    right = compare(node1.right, node2.right)
    if right != 0:
        return right

    return 0

【讨论】:

  • 哦,非常感谢您的帮助,我现在明白这个错误了!我非常感谢 :) 是的,我最初是用 Java 实现的,但我想遵循最小可复制示例的指导方针。我的 Java 代码已经接近最低限度,所以我把它变成了伪代码哈哈!再次感谢您!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-24
  • 2022-06-27
  • 1970-01-01
  • 2011-04-26
  • 1970-01-01
  • 2015-12-20
  • 1970-01-01
相关资源
最近更新 更多