-1

This seems like it should be really easy but I've been having trouble with this for quite some time. As the title says, I'm just trying to find the node in a Binary tree (not a BST!) with the smallest value and return it. I can write a recursive void function pretty easily that can at least assign the smallest value in the function, but I'm getting stuck on how to back track to previous nodes once I reach a NULL pointer.

I have a node class that has a pointer to a left and right child, each with its own value. Here is my (failed) attempt so far:

int preOrder(Node *node, int value, int count, int sizeOfTree)
{
  count++; //keeps track of whether or not we have traversed the whole tree

  if(value < node->getValue())
    value = node->getValue(); 

  if(count == sizeOfTree);
    return value;

  if(node == NULL)
    //Want to return to the previous function call
    //How do I do this for a non void function? 
    //for a void function, you could jsut type "return;" and the function
    //back tracks to your previous place in the tree
    //but since I'm returning a value, How would I go about doing this?

  //these 2 calls are incorrect but the idea is that I first traverse the left subtree
  //followed by a traversal of the right subtree.
  preOrder(node->getLeft(), value);

  preOrder(node->getRight(), value);

}

If possible, I would like to try and do this without keeping track of a "count" as well to make the code cleaner. Let me know if anymore clarification is needed.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Wakka Wakka Wakka
  • 271
  • 1
  • 9
  • 16
  • Quick & dirty method: Create a static global that you initialize with `INT_MAX` and you overwrite it in your recursive calls each time you find a value smaller than it... – Mihai Todor Jul 30 '12 at 19:27
  • You have to use a single "global" count variable, instead of passing the count by value. Turn your *count* argument into a pointer, and, before you start the traversal, declare one *count* variable, and pass its address to preOrder(). In preOrder(), access this variable through the pointer, and for recursive calls, just pass the *count* pointer. – Ambroz Bizjak Jul 30 '12 at 19:28
  • e.g. something like: preOrder(..., int *count, ...) { (*count)++; – Ambroz Bizjak Jul 30 '12 at 19:29
  • @AmbrozBizjak Actually, he can also pass it by reference, to avoid pointer headaches (since it's supposed to be C++ code) – Mihai Todor Jul 30 '12 at 19:29
  • @MihaiTodor or he can pass it by pointer, since that makes it more clear that it is supposed to be modified. This is not the place to have religious discussions over which of the duplicate features of C++ to use :) – Ambroz Bizjak Jul 30 '12 at 19:31
  • @AmbrozBizjak Well, I don't know about you, but I'll laugh if his next question is about "weird null pointer exceptions during recursive calls" :D – Mihai Todor Jul 30 '12 at 19:35

3 Answers3

6

I don't really understand why, in your original code, you need to keep track of the amount of elements traversed. Here is my solution:

int find_min(Node* node)
{
  int value = node->getValue()

  Node* left_node = node->getLeft();
  if (left_node != NULL)
  {
    int left_value = find_min(left_node);
    if (left_value < value)
      value = left_value;
  }

  Node* right_node = node->getRight();
  if (right_node != NULL)
  {
    int right_value = find_min(right_node);
    if (right_value < value)
      value = right_value;
  }

  return value;
}
Zimano
  • 1,870
  • 2
  • 23
  • 41
yuri kilochek
  • 12,709
  • 2
  • 32
  • 59
1

Basically what you need to do is just visit every node and keep track of the smallest value you've seen. This can actually be done fairly simply:

#include <algorithm>
#include <limits>

int preOrder(Node *node)
{
  if(node == NULL) return std::numeric_limits<int>::max();
  // this should never affect the calculation of the minimum
  // (What could possibly be bigger than INT_MAX? At worst it's equal)

  int value = std::min(
    node->getValue(),
    preOrder(node->getLeft())
    );

  value = std::min(
    value,
    preOrder(node->getRight())
    );

  return value;

}
Gordon Bailey
  • 3,881
  • 20
  • 28
1

OK, so you have an unordered binary tree and you're trying to find the lowest element in it.

Since the tree is unordered, the lowest element can be at any position in the tree, so you must search the entire tree.

The characteristics of the search will be as follows:

  • thorough (whole tree is searched)
  • recursive (rather than iterative, which would be really yucky)
  • base case: node is NULL
  • base outcome: maintain current value

Lets write it then:

#include <algorithm>
using namespace std;

int searchLowest(Node * node, int value = INT_MAX)
{
    if (node == NULL) // base case
        return value; // base outcome

    // at this point, node must not be NULL

    value = min(value, preOrder(node->getRight(), value)); // thorough, always recurse
    value = min(value, preOrder(node->getLeft (), value)); // and check children
    value = min(value, node->getValue());
    return value;
}

Edit for thoroughness, justice, and OOness:

// Node.h
#include <algorithm>
using namespace std;

template <typename T>
class Node
{
public:
    Node(T item)
    {
        data = item;
    }

    T lowest()
    {
        T value = data;

        if (right != NULL)
            value = min(value, right->lowest());
        if (left  != NULL)
            value = min(value, left->lowest());

        return value;
    }

    Node<T> * getRight()
    {
        return right;
    }

    Node<T> * getLeft()
    {
        return left;
    }

private:
    T data;

    Node<T> * right;
    Node<T> * left;
};

// main.cpp
#include <iostream>
#include "Node.h"
using namespace std;

int main(int c, char * v[])
{
    Node<int> * tree = sycamore(); // makes a nice big tree

    cout << tree->lowest();
}

SEE JIMMY RUN

Wug
  • 12,956
  • 4
  • 34
  • 54