0

How can I search for an element in a binary tree that is not a bst?

This is an example of how my tree looks

      1
     / \
    2   3
   / \ / \
  4  5 6  7

This is what I'm doing:

treeNode * find(treeNode *T, int x) {
    if(T == NULL) return NULL;
    if(x == T -> element) {
        return T;
    }
    find(T -> left, x);
    find(T -> right, x);
    return NULL;
}

The problem is that the recursion does not stop when the if is satisfied

10
  • 2
    Have you tried checking every node to see if it's the element you're looking for? If so, what issues are you having with that solution? If not, give that a try. Commented May 27, 2021 at 15:20
  • 1
    Depth-First Search should be covered in any decent algorithm text-book. Seems like you setup your example for a breath-first search which is slightly more difficult to implement than DFS. Commented May 27, 2021 at 15:21
  • 1
    When you recursively call find, you should do something with the return values. That's how you detect a successful search, no? Commented May 27, 2021 at 15:24
  • 1
    Your mistake is that you never check what the recursed function is returning. Commented May 27, 2021 at 15:25
  • 2
    afaik this is the topmost confusion with recursion. I find it interesting, because its only with recursion that beginners expect return values to magically travel up the call stack. Try to forget about the recursion for a moment and consider that the very first call can only return NULL unless it is already the searched for element. Commented May 27, 2021 at 15:28

5 Answers 5

3

You're ignoring the return values from your recursive calls:

treeNode * find(treeNode *T, int x) {
    if(T == NULL) return NULL;
    if(x == T -> element) {
        return T;
    }
    treeNode *result = find(T -> left, x);
    if ( result ) // if the return value was found, this will not be NULL, so return the node
        return result;
    return find(T -> right, x); // will return NULL if its not found
}
Sign up to request clarification or add additional context in comments.

Comments

3

You're missing return statements for your recursive calls. So not only does the recursion continue, but the value is never returned to the original caller.

treeNode * find(treeNode *T, int x) {
    if(T == NULL) return NULL;
    if(x == T -> element) {
        return T;
    }
   auto findLeft = find(T -> left, x)
   if (findLeft) return findLeft;
   return find(T -> right, x);
}

1 Comment

Ah, I'm not familiar with cpp and assumed it would return whichever ptr is truthy. Thanks for pointing it out.
2

In context to -

The problem is that the recursion does not stop when the if is satisfied

-the reason is because you must check if your recursive calls return a valid result and stop searching further.

Change -

find(T -> left, x);
find(T -> right, x);

-to something like -

    treeNode* result = find(T -> left, x);
    if (result != NULL)
        return result;
    return find(T -> right, x);

Comments

2

Look at the results of each attempt to find x

treeNode * find(treeNode *T, int x) {
    if(T == NULL) return NULL;
    if(x == T -> element) {
        return T;
    }
    treeNode* result = find(T -> left, x);
    if (result)
        return result;

    result = find(T -> right, x);
    if (result)
        return result;

    return NULL;
}

ETA: the end of this can be simplified. Returning result if it's not NULL and returning NULL otherwise... is the same as returning result. All we're doing, really, is returning the value returned from the call to find. So...

treeNode * find(treeNode *T, int x) {
    if(T == NULL) return NULL;
    if(x == T -> element) {
        return T;
    }
    treeNode* result = find(T -> left, x);
    if (result)
        return result;

    return find(T -> right, x);
}

Comments

0

Binary trees are usually used to keep data sorted and quickly add/find items in that order.

Without order binary tree doesn't have many applications. So when I see your picture of tree I suspect that you have missed most important property of b-trees and probably important part of your task.

If you note that order is important in your task then take a look at that code:

class Node;

using NodePtr = std::uniqeu_ptr<Node>;
class Node
{
    int value;
    NodePtr left;
    NodePtr right;
};

void insert(NodePtr &node, int value)
{
    if (node) {
       insert((value < node->value) ? node->left : node->right, value);
    } else {
       node.reset(new Node{value});
    }
}

Node* find(Node* node, int value)
{
    if (!node) {
       return nullptr;
    }
    if (node->value == value) {
       return node.get();
    }
    return find((value < node->value) ? node->left.get() : node->right.get(), value);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.