javatreetree-search

How to stop tree search after child was found


The following is failing to return the correct child node, even though it is actually finding the child further up the tree. It appears to drop the child after finding it, ad proceed to just keep searching the rest of the tree.

private Node<K, V> getNode(K key, ArrayList<Node<K, V>> children){
    if (children == null) return null;

    if (root.getKey().equals(key)) return root;

    for (Node<K, V> child : children) {
        if (child.getKey().equals(key)) return child;
        getNode(key, child.getChildren());
    }

    return null;
}

I tested it with the following code:

Tree<Integer, String> tree = new Tree<>(1, "1");

tree.addChild(1, new Node<>(2, "2"));
tree.addChild(1, new Node<>(3, "3"));
tree.addChild(1, new Node<>(4, "4"));
tree.addChild(2, new Node<>(5, "5"));

System.out.println(tree.addChild(5, new Node<>(6, "6")));
System.out.println(tree.addChild(5, new Node<>(7, "7")));

However, the console outputs false both times, even though it should be true. The child with a key of 5 cannot be found, even though I added one to the tree.


Solution

  • The problem is that when you look for a child in a subtree, you ignore the return value:

    if (child.getKey().equals(key))
    {
        // This is fine
        return child;
    }
    else
    {
        // This is bad: you ignore the return value.
        getNode(key, child.getChildren());
    }
    

    To fix, capture the return value, and return it if it is not null, like this:

    if (child.getKey().equals(key))
    {
        return child;
    }
    else
    {
        Node<K, V> res = getNode(key, child.getChildren());
        if (res != null) {
            return res;
        }
    }
    

    In addition, your code will miss the situation when the value is stored at the root, and the root has no children, because the root.getKey().equals(key) is not done on nodes that have no children.