简体   繁体   中英

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

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 > node 2 
                return 1
            
            else if node1 = node 2
                return 0
            
            else if node1 < 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.

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: '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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM