0

I have created a program which contains a class Node, for representing a binary tree of any type(template).

In my Node.h class, I have two constructors, however I am not sure if I implemented both of them correctly. Initialising the values within the constructors has confused me. In my main.cpp file, I have a setUpTree function. My program executes now, but doesnt print the tree that is set up.

I have tried for hours trying to fix this but to no ends. I am not really experienced with C++, pointers, constructors etc yet.

I would appreciate it if anyone could help me fix my code so that the setUpTree function works, and also the printTree method.

Thanks

Node.h Class:

   #ifndef NODE_H
#define NODE_H
#include <iostream>
#include <string>
using namespace std;

//an object of type node holds 3 things
// - an item (of type t)
// - a left subtree
// - a right subtree

template<typename T>
class Node {
public:
    Node(T item); //constructor to create a leaf node
    Node(T item, Node *lft, Node *rht); //constructor which creates an internal node 
    ~Node(); //Destructor

    //public data member functions:
    bool searchTree(T key);
    void printTree();

private:
    //private data member functions:
    Node* left;
    Node* right;
    T item;
};

//constructor 
template<typename T>
Node<T>::Node(T i, Node<T> *lft, Node<T> *rht) {
    item = i;
    left = NULL;
    right = NULL;
}

//constructor 
template <typename T>
Node<T>::Node(T i) { //should i be a parameter here?
    item = i; //is this right for this constructor?
}

//destructor
template <typename T>
Node<T>::~Node() {
    delete left;
    delete right;
    //delete;
}


//print tree method
template <typename T>
void Node<T>::printTree() {
    if (left != NULL) {
        left->printTree();
        cout << item << endl;//alphabetical order
    }

    if (right != NULL) {
        right->printTree();
        //cout << item << endl; //post order
    }
}

//search Tree method
template <typename T>
bool Node<T>::searchTree(T key) {
    bool found = false;
    if (item == key) {
        return true;
    }
    if (left != NULL) {
        found = left->searchTree(key);
        if (found) return true;
    }
    if (right != NULL) {
        return right->searchTree(key);
    }
    return false; //if left and right are both null & key is not the search item, then not found == not in the tree.
}

#endif

Main.cpp Class:

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

//set up tree method
Node<string> *setUpTree() {
    Node<string> *s_tree =
        new Node<string>("Sunday",
        new Node<string>("monday",
        new Node<string>("Friday"),
        new Node<string>("Saturday")),
        new Node<string>("Tuesday",
        new Node<string>("Thursday"),
        new Node<string>("Wednesday")));
    return s_tree;
}

int main() {

    Node<string> *s_tree;
    s_tree = setUpTree(); //call setUpTree method on s_tree

    cout << "Part 2 :Printing tree values: " << endl;
    s_tree->printTree(); //call print tree method

    cout << endl;

    //search for range of tree values
    //searchTree(s_tree, "Sunday");
    //searchTree(s_tree, "Monday");

    return 0;
}
Liam
  • 429
  • 1
  • 13
  • 33

2 Answers2

2

First the return in setupTree should be s_tree.

Second you construct a binary tree by adding each item one at a time. I would suggest making setupTree accept an array of values that you can then take one at a time and build the tree.

As was pointed out the default values for left and right should be NULL. However, I would just do it in the declaration, so that you don't have to repeat it in every constructor where the values aren't specified:

private:
    //private data member functions:
    Node* left = NULL;
    Node* right = NULL;
    T item;
tinstaafl
  • 6,908
  • 2
  • 15
  • 22
  • thanks, stupid mistake. are the constructors correct in my Node.h class? and also not sure what the brackets are all about in the setUpTree method the lecturer only showed the slides for a few secs so not too sure if they are correct – Liam Dec 14 '16 at 16:50
  • Other than ,as pointed out by `max66`, using NULL as default values for the sub nodes, they seem OK to me. – tinstaafl Dec 14 '16 at 16:55
  • I think the lecturer was probably showing you how he/she wanted the data organized. You have to re-write your code to take an array of values and iterate through them one at a time and add them to the tree. – tinstaafl Dec 14 '16 at 17:02
1

I don't know if it's the only problem but... if you construct a leaf, you have to set left and right pointers to NULL

template <typename T>
Node<T>::Node(T i) : left(NULL), right(NULL), item(i)
 { }

otherwise, when the destructor is called

template <typename T>
Node<T>::~Node() {
    delete left;
    delete right;
    //delete;
}

delete is called over undefined values; two times.

It's a perfect recipe for a crash.

Other problems in every point you use left or right checking if the pointer is NULL, as made in printTree() or searchTree(): the value is undefined, so can be non NULL, pass the test and printTree() is called over a pointer with an undefined value

-- EDIT --

Suggested contructors.

template <typename T>
Node<T>::Node (T i, Node<T> * lft, Node<T> * rht)
 : left(lft), right(right), item(i)
 { }

template <typename T>
Node<T>::Node (T i)
 : left(NULL), right(NULL), item(i)
 { }

--- EDIT 2 ---

it is now printing some values at least ; monday sunday tuesday. not sure about the rest

Look at your printTree() metod

template void Node::printTree() { if (left != NULL) { left->printTree(); cout << item << endl;//alphabetical order }

if (right != NULL) {
    right->printTree();
    //cout << item << endl; //post order
}

}

It print the value (item) only if left isn't NULL. So it doesn't print the value of the leafs.

Suggestion: modify printTree() to print item even when left is NULL.

By example

template <typename T>
void Node<T>::printTree() {
    if (left != NULL) {
        left->printTree();
    }

    cout << item << endl;

    if (right != NULL) {
        right->printTree();
    }
}
max66
  • 65,235
  • 10
  • 71
  • 111
  • I changed my code, so the constructor, now sets them to NULL template Node::Node(T i, Node *lft, Node *rht) { item = i; left = NULL; right = NULL; } is this what you mean? – Liam Dec 14 '16 at 16:48
  • @Liam - yes; I suggest to inzialize the values in the initialization list (sorry: forgetted a `:`; corrected now) but your correction should be enough. – max66 Dec 14 '16 at 16:51
  • program executes now without crashing but doesn't print any values – Liam Dec 14 '16 at 16:56
  • @Liam - sorry but I see it only now: you have changed the wrong constructor; the constructor that receive `lft` and `rht` was right; is in the constructor that receive *only* a `T` that you have to impose `left = right = NULL`. – max66 Dec 14 '16 at 17:15
  • so the second constructor that only receives T i : template Node::Node(T i) { item = i; left = NULL; right = NULL; } ? – Liam Dec 14 '16 at 17:22
  • @Liam - yes: only the second (leaf case) contructor. – max66 Dec 14 '16 at 17:51
  • what do you mean? the first constructor shouldnt be setting them to NULL ,only the second constructor should? – Liam Dec 14 '16 at 18:09
  • @Liam - answer improved; I suggest you to delete your constructor and use the two suggested. – max66 Dec 14 '16 at 18:16
  • very good, it is now printing some values at least ; monday sunday tuesday. not sure about the rest. what is the difference in these constructors? – Liam Dec 14 '16 at 18:42
  • 1
    @Liam - improved answer to print leaf nodes; about difference in constructor, search for "initialization list"; look, by example, [this question](http://stackoverflow.com/questions/926752/why-should-i-prefer-to-use-member-initialization-list) and first answer – max66 Dec 14 '16 at 18:54
  • it prints them alphabetically now after making that change to the printTree method. Thanks appreciate it. – Liam Dec 14 '16 at 19:46
  • when i un-comment one of the searchtree calls, it says error: identifier searchTree is undefined? – Liam Dec 14 '16 at 19:55
  • never mind, fixed it! had to put call it by s_tree->searchTree(key). – Liam Dec 14 '16 at 20:15