Reputation: 3
I'm using Java for a Binary Tree (not a Binary Search Tree). I have the class and instance variable declarations:
class intBTNode
{
private int data;
private intBTNode left;
private intBTNode right;
What I want to do is write a method which returns true only if all of the entries in the tree are equal to a target number or if the tree is empty. I wrote the following code:
public static boolean allEqual(intBTNode root, int target)
{
if (root == null)
return true;
if (root.data == target && root.left != null)
return allEqual(root.left, target);
if (root.data == target && root.right != null)
return allEqual(root.right, target);
return false;
}
I'm trying to work my way through this to check the code, but I am not sure I am adequately checking all of the nodes (i.e. the leaf). Also, I am trying to work out a way to attack this problem that is not recursive or would be more efficient. Any help or suggestions would be appreciated.
Upvotes: 0
Views: 62
Reputation: 183270
You are not adequately checking all nodes.
The problem is that if root.left
is non-null, then you never examine root.right
; so a tree like this:
3
/ \
3 4
will be mis-classified as containing only the target.
A better approach is to write:
public static boolean allEqual(intBTNode root, int target)
{
return root == null
|| root.data == target
&& allEqual(root.left, target)
&& allEqual(root.right, target);
}
If you want to avoid recursion for some reason, you can do that by maintaining a collection of nodes that you've "discovered" (by visiting their parent) but haven't yet actually "visited" (by examining their data
and children), and continually pulling nodes out of that collection, and visiting them, until it's empty:
public static boolean allEqual(intBTNode root, int target)
{
List<intBTNode> nodesToVisit = new ArrayList<intBTNode>();
nodesToVisit.add(root);
while (! nodesToVisit.isEmpty()) {
intBTNode node = nodesToVisit.remove(nodesToVisit.size() - 1);
if (node == null)
continue;
if (node.data != target)
return false;
nodesToVisit.add(node.left);
nodesToVisit.add(node.right);
}
return true;
}
(This is actually exactly equivalent to the recursive version, just using an ArrayList
as a stack instead of using the call stack.)
Upvotes: 1
Reputation: 5564
You should replace
if (root.data == target && root.left != null)
return allEqual(root.left, target);
if (root.data == target && root.right != null)
return allEqual(root.right, target);
return false;
With
return root.data == target && allEqual(root.left, target) && allEqual(root.right, target);
Since your current code ignores the right subtree (and also, the null checks are redundant because you check each time if the root is null)
As for avoiding recursion, you could use a different while
loop, pushing the children of the current node into a stack (initialized with the root) and always popping the first element. (Of course, while data == target
)
Upvotes: 0