views:

578

answers:

5

Hi I'm stuck doing this, not sure how to go about it.

If I have two binary trees, how would I check if the have the same shape? Data in the nodes doesn't matter, just if the tree structures are equal.

Any ideas on how to solve this problem?

+1  A: 

Two Breadth First Searches in parallel would be one way.

http://en.wikipedia.org/wiki/Breadth-first_search

With BFS, you can examine all nodes a particular level of the tree at the same time. That way, if you don't distinguish between right and left children (i.e. if your tree is considered the same if a node's counterpart has one child, regardless of "right" or "left" child) you can handle that at that time.

Sam Hoice
A: 

Walk them in pre-order and in-order with symbolic names instead of the actual data and compare the resulting Strings. Maybe some more input on your data structure would be usefull.

Not java related AFAICT

Marcelo Morales
+2  A: 

If I have two binary trees, how would I check if the have the same shape?

You will be pleased to know that binary trees have an interesting property: they can be represented as arrays. Simply convert each tree to one of these arrays and compare the array contents. Blank cells correspond to left or right children that don't exist, defining the structure of the tree. You want to iterate over both arrays and make sure that each blank cell encountered in one array appears in the other array; this is O(n).

Of course, if the arrays are different sizes, you don't have to do any work at all, since trees with different numbers of nodes can't possibly have identical structure. From there, you're all done.

John Feminella
In Java, you're still going to have to iterate through the arrays to do the comparison. Unless you're representing the binary tree as an array in the first place, why not just do the comparison as you traverse the tree and save yourself a second traversal and the space for the array?
Sam Hoice
@Sam: The primary reason you'd want to use the array representation instead is clarity. The same kind of comparison is performed for each array iteration, as opposed to a tree, where each child of a tree node will probably be named differently (left, right, etc.).
John Feminella
@Sam: Also, yes, I assumed he'd be representing the tree as an array in the first place (since that is in fact a valid structure for binary trees). If that's not the case then this has somewhat less benefit, but it's still a useful means of comparison.
John Feminella
The array becomes really (impractically) big, though.
v3
Actually, an array representing a complete binary tree is maximally efficient (more so than the binary tree representation itself).
John Feminella
A: 

Just follow the branches, mimicking each move in one tree in the other. In Python pseudo-code:

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

def same_shape(T1, T2):
    if T1 == None:
        return T2 == None

    if T2 == None:
        return T1 == None

    return same_shape(T1.left, T2.left) and same_shape(T1.right, T2.right)
Stephan202
+6  A: 

You can easily do that with recursion. This following code works because two non-empty trees have the same shape if and only if their respective subtrees have the same shape.

boolean equalTrees(Node lhs, Node rhs)
{
    // Empty trees are equal
    if (lhs == null && rhs == null)
        return true;

    // Empty tree is not equal to a non-empty one
    if ((lhs == null && rhs != null)
        || (lhs != null && rhs == null))
        return false;

    // otherwise check recursively
    return equalTrees(lhs.left(), rhs.left())
        && equalTrees(lhs.right(), rhs.right())
}

To check two trees, pass their root nodes to the function above.

equalTrees(tree1.root(), tree2.root())
avakar
I like recursion. +1
GoatRider
I think the first 2/3 of that method is simply "if (lhs == null || rhs == null) { return ((lhs==null) == (rhs==null)); }".
Ken
Ken, you're right, your code is equivalent and shorter. I would still write it my way as I find it more readable.
avakar