中序遍历两个二叉树以比较哪一个更大。

huangapple go评论78阅读模式
英文:

In-order traversal of two binary trees to compare which one is bigger

问题

我试图找到一种比较二叉树节点的方法,以确定一个树的节点是否比另一个树的节点更"大"。我想要比较的方式是通过比较最左节点、根节点,然后是最右节点来进行的。我认为实现这个的最佳方式是使用递归执行中序遍历,并通过这种方式比较节点。

然而,当递归调用函数时,我在找到它返回正确答案方面遇到了困难。递归真的让我感到困惑,不知道程序在做什么。我有的是以下代码:

function binaryTreeComparison(node1, node2) {

        if node1  node2 都为空
            返回 0
        
        if node1 不为空 node2 为空
            返回 1
        
        if node1 为空 node2 不为空
            返回 -1
        
        否则 {
            binaryTreeComparison(node1.getLeftChild(), node2.getLeftChild())

            if node1 > node2 
                返回 1
            
            else if node1 = node2
                返回 0
            
            else if node1 < node2 
                返回 -1
            
            binaryTreeComparison(node1.getRightChild(), node2.getRightChild());
        }
        返回 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。谢谢您的帮助。我在许多其他地方搜索了帮助,但是我无法弄清楚这个问题。

英文:

I'm trying to find a way to compare the nodes in a binary tree to see whether the nodes of one tree are "bigger" than the other. The way in which I want to compare them is by comparing the leftmost nodes, the root, then the rightmost nodes. I thought the best way to do this would be to perform an in-order traversal using recursion and comparing the nodes that way.

However, I'm having trouble finding a way for it to return the correct answer when recursively calling the function. Recursion really has a way of confusing me and losing track of what the program is doing. What I have is the following:

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 &gt; node 2 
                return 1
            
            else if node1 = node 2
                return 0
            
            else if node1 &lt; node2 
                return -1
            
            binaryTreeComparison(node1.getRightChild(), node2.getRightChild());
        }
        return 0
    }

Apologies for my attempt at pseudocode. Was trying to create a minimal, reproducible example. What's happening, instead of breaking off and returning the first instance of a node being different, it instead I think returns the "top of the recursion pile" and I don't know any way to get around this. I'm sure it has something to do with how I'm not doing something like return binaryTreeComparison(node1.getLeftChild(), node2.getLeftChild());. For example, if we have two binary trees like such:

     4           4
    / \         / \
   2   5       6   5

Then it should return -1 after visiting the bottom-left node, since 6 > 2. What happens instead is that it returns 0 because it compares 4 = 4 at the top of the tree. Another example for trees of different heights would be:

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

Here the left tree would be greater than the right tree, thus returning 1. Thank you for your help. I searched many many other places for help, but I couldn't figure this out.

答案1

得分: 0

以下是翻译好的内容:

基本上,你的结构是正确的。我认为你在过多考虑沿左侧先遍历的问题。这似乎是初学递归时人们经常犯的一个错误。在学习时,我经常犯这个错误。相反地,使用递归,你可以将问题缩小到最基本的情况,然后让递归处理它们。在这种情况下,我认为有很多情况:

  1. node1 为 null 而 node2 也为 null
  2. node1 为 null 而 node2 不为 null
  3. node1 不为 null 而 node2 为 null
  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 和 node2.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
    # 这是你的错误
    # 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
英文:

Small note, your code is not truly reproducible because it is pseudocode, so I'm not 100% sure that I got your problem correct because I don't know if this problem is actually in your code. It would be useful to actually see your real code in the language you're using without things that are irrelevant to the problem.

However, I have implemented what you described in your prose and your pseudocode, and I believe I am experiencing the behavior you are. I'm still not quite 100% sure I understand what you want exactly out of comparison, but I hope this makes sense:

Basically, your structure is correct. I think you're overthinking the traversing down the left first side. This seems to be a common problem people make when learning recursion. I made this problem often when I was learning. Instead, with recursion you can narrow things down to the most basic cases and let the recursion handle applying them. In this case, I think you have a significant number of cases:

  1. node1 is null and node2 is null
  2. node1 is null and node2 is not null
  3. node1 is not null and node2 is null
  4. node1's left child != node2's left child
  5. node1's value != node2's value
  6. node1's right child != node2's right child
  7. node1 == node2

I don't know exactly what your code looks like. In your pseudo-code, there are two major issues. I assume the first issue isn't actually in your code which is that when you recurse, you aren't checking and returning the result. You only want to return the result if it != 0. So, instead of:

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

You want

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

The key issue with your code is that you've duplicated condition (7). This explains the behavior you're experiencing with:
> instead of breaking off and returning the first instance of a node being different, it instead I think returns the "top of the recursion pile" and I don't know any way to get around this

You actually just want to delete this, as once you check node1.value < node2.value and node2.value > node2.value, you know that node1.value == node2.value. But, you have to wait until after you check the right side before returning 0, otherwise you will always ignore the children on the right. Trust that the return 0 at the bottom will work 中序遍历两个二叉树以比较哪一个更大。

Here's working code in Python:

from dataclasses import dataclass

@dataclass
class Tree:
    value: int
    left: &#39;Tree&#39; = None
    right: &#39;Tree&#39; = None

def compare(node1: Tree, node2: Tree) -&gt; 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 &gt; node2.value:
        return 1
    # This is your bug
    # if node1.value == node2.value:
    #     return 0
    if node1.value &lt; node2.value:
        return -1

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

    return 0

huangapple
  • 本文由 发表于 2020年9月29日 00:34:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/64106162.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定