I have a lab assignment that I have been working on for the last couple of weeks and I am stuck and desperately need help as this will be about 50% of the final project.
The assignment is to create a Binary Search Tree in C++. We have to read in the words from the Declaration of Independence into a Binary Search Tree. I have my search and insert methods "working properly" meaning that they aren't throwing any errors. The problem I am having is displaying the BST to figure out if everything is working properly. The display method should be called by the overloaded operator >> to display the tree.
The errors I keep getting are:
"error C3867: 'BST::display': function call missing
argument list; use '&BST::display' to create a pointer to
member"
and the other one is
"error C2679: binary '<<' : no operator found which takes a right-hand
operand of type 'overloaded-function' (or there is no acceptable
conversion)."
Last time I rebuilt the program it shows "ItelliSense: a pointer to a bound function may only be used to call the function."
#include "stdafx.h"
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
template <typename T>
class BST{
private:
struct node {
T data;
struct node* left;
struct node* right;
};
node* root;
public:
BST()
{
root = NULL;
}
bool isEmpty() const { return root == NULL; }
~BST();
template <typename T>
void insert(T d)
{
node* t = new node;
node* parent;
t->data = d;
t->left = NULL;
t->right = NULL;
parent = NULL;
if (isEmpty()) root = t;
else {
node* current;
current = root;
while (current)
{
parent = current;
if (t->data > current->data) current = current->right;
else current = current->left;
}
if (t->data < parent->data)
parent->left = t;
else
parent->right = t;
}
}
template<typename T>
bool search(T d)
{
if (root == NULL)
return false;
else if (d == root->item) {
return true;
}
else if (d < root->item) {
return search(root->left, d);
}
else {
return search(root->right, d);
}
}
template<typename T>
void display(node *p, std::ostream& os)
{
if (p != NULL)
{
if (p->left) display(p->left);
os << " " << p->data << " ";
if (p->right) display(p->right);
}
}
template<typename T> friend std::ostream& operator<<(std::ostream& os, const BST<T>& obj)
{
obj.display(os, obj.root);
}
};
int main( )
{
BST<string> s;
ifstream inFile;
string word, tmp;
string filename = "Independence.txt";
ifstream fstr(filename.c_str());
while (inFile >> word) {
s.insert(word);
}
inFile.close();
cout << s << std::endl;
cout << "Search for: ";
cin.ignore(1);
cin >> tmp;
s.search(tmp);
return 0;
};
template<typename T>
void display(node *p)
This takes a parameter with a node pointer.
Then you call it later with:
BST<string> s;
cout << s.display << endl;
But you don't actually pass it any parameters here. The compiler then complains it can't figure out how to call that function. Because that function has a return type of void it can't figure out how to print it as you aren't actually returning anything for cout to print. You will want to fix both these problems before you move on, given that you said it's an assignment I'll leave you to figure out how to do that :).
There seem to be a number of problems with your code. I suspect display and search should not be separately templated - this would actually be a template member function inside a template class and I don't think that's what you intended. Also, the search function refers to node::item, but the declaration of the node type has node::data. Finally, BST::display is written to be a void function taking a node in a way that it could be declared static but your usage is as if you expect it to work like a member function. It doesn't return anything so it certainly can't be passed to iostream::operator<<. Better would be to have display take the iostream as input and then call it as either root->display(cout) or display(cout, root) depending on whether you want it to be a member function or a static function.
you have a couple of concept errors,
the display method returns void so you cannot pass it to cout that expect something to show.
So, the easy change for you will be to add a new method called display_tree like this
void display_tree()
{
display(root);
}
and in your main only call the method
s.display_tree();
not like this
cout << s.display << std::endl; //this is wrong cause this is not even calling a method
another option is to override the << operator, but editing your diplay method like this
template<typename T> void display(node *p, std::ostream& os)
{
if (p != NULL)
{
if (p->left) display(p->left);
os << " " << p->data << " ";
if (p->right) display(p->right);
}
}
and then outside your class
template<typename T> friend std::ostream& operator<<(std::ostream& os, const BST<T>& obj)
{
obj.display(obj.root);
}
and call it in your programa like this
cout << s << std::endl;
in order to this to work, the T needs to have the operator << overloaded (which is the case of the string in your case)
try with this instead -- new version compiling
void display(node *p, std::ostream& os) const
{
if (p != NULL)
{
if (p->left) display(p->left,os);
os << " " << p->data << " ";
if (p->right) display(p->right,os);
}
}
template<typename T> friend std::ostream& operator<<(std::ostream& os, const BST<T>& obj)
{
obj.display(obj.root,os);
return os;
}
Here is your code compiling and fixed the search
#include "stdafx.h"
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
template <typename T>
class BST{
private:
struct node {
T data;
struct node* left;
struct node* right;
};
node* root;
template<typename T> bool search(node* p, T d)
{
if (!p) {
return false;
}
if (d == p->data) {
return true;
}
else if (d < p->data) {
return search(root->left, d);
}
else {
return search(root->right, d);
}
}
public:
BST()
{
root = NULL;
}
bool isEmpty() const { return root == NULL; }
~BST();
template <typename T>
void insert(T d)
{
node* t = new node;
node* parent;
t->data = d;
t->left = NULL;
t->right = NULL;
parent = NULL;
if (isEmpty()) root = t;
else {
node* current;
current = root;
while (current)
{
parent = current;
if (t->data > current->data) current = current->right;
else current = current->left;
}
if (t->data < parent->data)
parent->left = t;
else
parent->right = t;
}
}
template<typename T> bool search(T d)
{
if (root == NULL)
return false;
else if (d == root->data) {
return true;
}
else if (d < root->data) {
return search(root->left, d);
}
else {
return search(root->right, d);
}
}
void display(node *p, std::ostream& os) const
{
if (p != NULL)
{
if (p->left) display(p->left,os);
os << " " << p->data << " ";
if (p->right) display(p->right,os);
}
}
template<typename T> friend std::ostream& operator<<(std::ostream& os, const BST<T>& obj)
{
obj.display(obj.root,os);
return os;
}
};
int main()
{
BST<string> s;
ifstream inFile;
string word, tmp;
string filename = "Independence.txt";
ifstream fstr(filename.c_str());
while (inFile >> word) {
s.insert(word);
}
inFile.close();
cout << s << std::endl;
cout << "Search for: ";
cin.ignore(1);
cin >> tmp;
s.search(tmp);
return 0;
};
Related
The way i used to search the Tree is through a recursion. I was wondering if I could break from the recursion and reach the program to it's normal flow.
So basically I'm trying to say is, Is there a way to break from a recursion without back tracking the stack?
If not can anyone suggest me some other way?
BinaryTree Class
class BinaryTree
{
public:
template <class T>
class Node {
public:
Node(T item) {
this->item = item;
this->left = nullptr;
this->right = nullptr;
}
Node* left;
Node* right;
T item;
};
BinaryTree();
template<class T>
void DFS(Node<T> *N);
private:
Node<char>* root;
};
BinaryTree::BinaryTree()
{
this->root = new Node<char>('A');
this->root->left = new Node<char>('B');
this->root->right = new Node<char>('C');
this->root->left->left = new Node<char>('D');
this->root->left->right = new Node<char>('E');
this->root->right->left = new Node<char>('F');
this->root->right->right = new Node<char>('G');
this->DFS(root);
}
template <class T>
void BinaryTree::DFS(Node<T>* N) {
if(N == nullptr)
return;
cout << N->item << endl;
if( N->item == 'E') {
cout << "found\n";
//Break from recursion;
}
DFS(N->left);
DFS(N->right);
}
Output Generated
A
B
D
E
found
C
F
G
Output Required
A
B
D
E
found
The simplest solution that came to my mind:
template <class T>
bool BinaryTree::DFS(Node<T>* N) {
if(N == nullptr)
return false;
cout << N->item << endl;
if( N->item == 'E') {
cout << "found\n";
return true;
}
if(DFS(N->left))
return true;
if(DFS(N->right))
return true;
return false;
}
You would, however, need to change the return type in the class declaration.
I had to write a program that handle this main code:(not allowed to change it)
list<int> iv;
iv["john"] = 23;
int ia = iv["john"]++;
int ib = iv["john"];
cout << ia << " " << ib << endl; // prints 23 24
try{
cout << iv["jack"] << endl; // should throw an exception
}catch(list<int>::Uninitialized&)
{
cout << "Uninitialized map element!" << endl;
};
Here is my code:
#ifndef EXAM_H
#define EXAM_H
#include <iostream>
#include <string>
using namespace std;
template <class TYPE>
class list
{
private:
struct node
{
TYPE value;
string index;
bool isInit;
node *next;
};
node *head;
node *current;
public:
class Cref
{
friend class list;
list& s;
string position;
Cref (list& ss, string pos): s(ss), position(pos) {};
public:
operator TYPE() const
{
return s.read(position);
}
Cref& operator = (TYPE val)
{
s.write(position,val);
return *this;
};
Cref& operator = (const Cref& ref)
{
return operator= ((TYPE)ref);
};
};
class Uninitialized{};
list ()
{
cout << "constructor\n";
head = NULL;
current = NULL;
}
~list ()
{
while (head)
{
node *t = head->next;
delete head;
head = t;
};
}
TYPE read (string ind) const
{
cout << "read\n";
node *t = head;
while(t)
{
if(t->index == ind && t->isInit == true) return t->value;
else t = t->next;
}
throw Uninitialized();
}
void write (string ind, TYPE value_)
{
cout << "write\n";
node *t = new node;
t->next = head;
head = t;
head->value = value_;
head->index = ind;
head->isInit = true;
}
TYPE operator[] (string ind) const
{
cout << "read\n";
node *t = head;
while(t)
{
if(t->index == ind && t->isInit == true) return t->value;
else t = t->next;
}
throw Uninitialized();
}
Cref operator[] (string ind)
{
return Cref(*this, ind);
}
};
#endif
Everything works great, but only when I comment out postincrementation operation in main program
int ia = iv["john"]++;
As you can see I have a struct node where I put all variables and I want to increment value by one in node where the key is "john". Is there any way to implement operator++ for this code ?
I am not allowed to use std::map.
The usual approach to your problem is defining the array subscript operators as
const TYPE& operator[](string ind) const;
TYPE& operator[](string ind);
In this way, you do not have to bother a single bit about the operator++: Since iv["John"] returns a reference to int, iv["John"]++ will call the int post-increment operator which is built-in.
Yes, I have already tried this solution, but compiler do not distinguish between reading and writing and still using non-const version. So I had to build proxy class Cref that helps to distinguish.
I have also already find a solution to operator++ problem.
This operation had to be from Cref level. I created
Cref& operator++ (int val)
{
s.increment(position,val);
return *this;
};
And increment function in main class body as follows:
void increment (string ind, int value_)
{
cout << "increment\n";
node *t = head;
while(t)
{
if(t->index == ind && t->isInit == true) t->value = t->value + 1;
t = t->next;
}
}
That fully solved my problem.
I am trying to use a class Student and declare it as a list type. I can pushback but without changing the List.h or Node.h how can I print the data in list2? The given print() function within List..h does not work :(
Node.h
#ifndef NODE_H
#define NODE_H
#include <string>
#include <iostream>
using namespace std;
template <typename T>
class Node {
private:
T data;
Node<T>* next;
public:
Node(T);
virtual ~Node(); // base class destructor must be virtual
template <typename U> friend class List;
};
template <typename T>
Node<T>::Node(T d) {
data = d;
next = NULL;
}
template <typename T>
Node<T>::~Node() {
}
#endif /* STRNODE_H */
List.h
#ifndef LIST_H
#define LIST_H
#include "Node.h"
// Singly linked list
template <typename T>
class List {
private:
Node<T>* head; // pointer to the first node
Node<T>* tail; // pointer to the last node
int count; // number of nodes in the list
public:
class OutOfRangeException{ }; // empty inner class for exception handling
List();
virtual ~List();
void push_back(T item);
void insert(int index, T item);
void remove(int index);
int indexOf(T item);
T get(int position); // OutOfRangeException is generated
bool isEmpty();
int size();
void print();
};
template <typename T>
List<T>::List() {
head = tail = NULL;
count = 0;
}
template <typename T>
List<T>::~List() {
Node<T>* discard;
while (head != 0) {
discard = head;
head = head->next;
delete discard;
}
}
// append an item at the end of the StrList
template <typename T>
void List<T>::push_back(T item) {
try {
Node<T>* newNode = new Node<T>(item);
if (head == 0) {
head = tail = newNode;
} else {
tail->next = newNode;
tail = newNode;
}
++count;
} catch (bad_alloc &e) {
cout << "memory allocation exception: " << e.what() << endl;
exit(1);
}
}
// insert an item at the specified index
template <typename T>
void List<T>::insert(int index, T item) {
try {
if (index < 0 || index > count) // push_back() if index == count
throw OutOfRangeException();
Node<T>* newNode = new Node<T>(item);
if (head == 0) { // empty
head = tail = newNode;
} else if (index == 0) { // at the start
newNode->next = head;
head = newNode;
} else if (index == count) { // at the end
tail->next = newNode;
tail = newNode;
} else { // insert in the middle
Node<T>* prevNode;
Node<T>* currNode = head;
for (int i = 0; i < index; i++) {
prevNode = currNode;
currNode = currNode->next;
}
// insert between 'prevNode' and 'currNode'
prevNode->next = newNode;
newNode->next = currNode;
}
++count;
} catch (bad_alloc &e) {
cout << "memory allocation exception: " << e.what() << endl;
exit(1);
}
}
// is the StrList empty?
template <typename T>
bool List<T>::isEmpty() {
return count == 0;
}
// remove the item at specified index
template <typename T>
void List<T>::remove(int index) {
if (index < 0 || index >= count)
throw OutOfRangeException();
if (index == 0) { // at the start
Node<T>* discard = head;
head = head->next;
delete discard;
} else {
Node<T>* prevNode;
Node<T>* currNode = head;
for (int i = 0; i < index; i++) {
prevNode = currNode;
currNode = currNode->next;
}
// remove 'currNode'
prevNode->next = currNode->next; // bypass
delete currNode;
if (index == count - 1) // last node was removed. Update 'tail'
tail = prevNode;
}
--count;
if (count == 0)
tail = NULL;
}
// retrieve the item at the given position of the StrList. position starts from 0.
// throws OutOfRangeException if invalid position value is given.
template <typename T>
T List<T>::get(int position) {
if (position < 0 || position >= count)
throw OutOfRangeException();
int loc = 0;
Node<T>* curr = head;
while (loc < position) {
++loc;
curr = curr->next;
}
return curr->data;
}
// Requirement:
// != operator of <class T> is used
template <typename T>
int List<T>::indexOf(T item) {
if (head == 0) {
return -1; // not found
} else {
int index = 0;
Node<T>* currNode = head;
while (currNode->data != item && currNode != NULL) {
currNode = currNode->next;
++index;
}
if (currNode == NULL) // not found thru the end
return -1;
else
return index;
}
}
// number of nodes in the StrList
template <typename T>
int List<T>::size() {
return count;
}
// Requirement:
// << operator for <class T> is used.
template <typename T>
void List<T>::print() {
cout << "*** StrList contents ***" << endl;
for (int i = 0; i < count; i++) {
cout << i << ": " << get(i) << endl;
}
}
#endif
Student.h
#include "List.h"
class Student {
private:
string name;
int id;
public:
Student();
Student(string a);
virtual ~Student();
friend ostream& operator<<(ostream &os, const Student& p);
bool operator!=(const Student &p) const;
bool operator==(const Student &p) const;
};
Student::Student() {
}
Student::Student(string a) {
name = a;
}
Student::~Student() {
}
ostream& operator<<(ostream &os, const Student& p) {
return os << p.name;
}
bool Student::operator==(const Student &p) const {
// Compare the values, and return a bool result.
if (name == p.name)
return true;
else
return false;
}
bool Student::operator!=(const Student &p) const {
return !(*this == p);
}
main.cpp
#include <iostream>
using namespace std;
#include "Student.h"
int main() {
cout << "\n*** StrList Test ***" << endl;
List<string> list;
list.push_back("zero");
list.push_back("one");
list.push_back("two");
list.push_back("three");
list.push_back("four");
list.push_back("five");
list.print();
list.insert(1, "inserted at position 1");
list.insert(0, "inserted at position 0");
list.insert(4, "inserted at position 4");
list.print();
cout << "removing at indexes 3, 0" << endl;
list.remove(3);
list.remove(0);
list.print();
list.insert(2, "inserted at position 2");
list.print();
cout << "five is at index " << list.indexOf("five") << endl;
cout << "two is at index " << list.indexOf("two") << endl;
//Test for my Student class implementation
// Student<string> st1; //Create new student Ryan Martin with id of 1
List<Student> list2;
Student stu("Ryan Martin");
list2.push_back(stu);
//list2.print();
//list2.push_back("Ryan");
//list2.PrintStudents(); //Test that the Student class successfully stored and can access
return 0;
}
The << operator must be defined for your Student class. To quote List.h:
// Requirement:
// << operator for <class T> is used.
template <typename T>
void List<T>::print() {
cout << "*** StrList contents ***" << endl;
for (int i = 0; i < count; i++) {
cout << i << ": " << get(i) << endl;
}
}
So in your Student class, you need to implement the operator<<(ostream &out);
Do it as a friend (friends are fun!):
friend std::ostream& operator<< (std::ostream &out, const Student &stu)
{
return out << stu.name << " id: " << stu.id << std::endl;
}
Here is a good reference:
http://www.learncpp.com/cpp-tutorial/93-overloading-the-io-operators/
If I understood you correctly, then you want to define operator<< for your student class, which you can do for example like this:
friend std::ostream & operator<<(std::ostream & os, const Student & s)
{
return os << s.name << " " << s.id << std::endl;
}
Note however that I have not tested this code and I haven't read all the snippets you posted,
so I might have understood you wrongly.
EDIT:
So after trying it out with Visual Studio, the full version of you student class should be like this:
#include "List.h"
class Student {
private:
string name;
int id;
public:
Student();
Student(string a);
virtual ~Student();
friend std::ostream & operator<<(std::ostream & os, const Student & s)
{
return os << s.name << " " << s.id << std::endl;
}
};
Student::Student() {
}
Student::Student(string a) {
name = a;
}
Student::~Student() {
}
Also not that you do not have to make the destructor in Student virtual unless you plan on having it as a base class for other classes.
the print function require an operator << to be defined on your student class and it's not the case
so define how a student will be display by << and it should work!
I have this simple question.
In the main function I do: bsearch_tree bs1; I announce on BST tree. Then I add nodes to that tree.
Then I announce on another BST tree: bsearch_tree bs2; and I add nodes(different) to it once again.
What it does, is adding to both tress bs1 and bs2 the same nodes.
For, when I print both trees I see that they are the same but they shouldn't be. It's wrong.
I tried to debug and found that when I add nodes it adds them to the same tree.
I somehow need to make the trees distinct.
I guess I have to make new instance of the class bsearch_tree but I can't change the Main function (limitation).
Here is the Header file:
#include<iostream>
using namespace std;
class tnode
{
private:
double data;
tnode *left;
tnode *right;
public:
tnode(double key);
friend class bsearch_tree;
friend void assist(tnode *tmp);
friend ostream& operator<<(ostream& stream,tnode const *root);
};
class bsearch_tree
{
tnode *root;
public:
bsearch_tree();
bsearch_tree(int);
void duplicate_tree(tnode *root,tnode **new_root);
void free_tree(tnode *node);
void add_value(double v);
tnode copy(tnode *root);
bsearch_tree operator + (const bsearch_tree & t);
bsearch_tree & operator=(const bsearch_tree & v);
friend void print(bsearch_tree tree);
friend ostream& operator<<(ostream& stream,bsearch_tree const root);
private:
void AddNode(double key,tnode *leaf);
void SumTree(tnode *tree);
};
And here is the Code file:
#include<iostream>
#include "head.h"
using namespace std;
tnode::tnode(double key)
{
this->data = key;
this->left = NULL;
this->right = NULL;
}
bsearch_tree::bsearch_tree()
{
bsearch_tree *root = new bsearch_tree(NULL);
//root = NULL;
}
bsearch_tree::bsearch_tree(int)
{
//bsearch_tree *root = new bsearch_tree(NULL);
root = NULL;
}
void bsearch_tree::duplicate_tree(tnode *root,tnode **new_root)
{
if(root == NULL)
return;
(**new_root) = copy(root);
}
tnode bsearch_tree::copy(tnode *root)
{
tnode* node = new tnode(root->data);
if(root == NULL)
return *node;
copy(root->left);
copy(root->right);
return *node;
}
void bsearch_tree::free_tree(tnode *node)
{
if(node == NULL)
return;
free_tree(node->left);
free_tree(node->right);
free(node);
}
void bsearch_tree::add_value(double v)
{
tnode *tmp;
if(root == NULL)
{
tmp = new tnode(v);
root = tmp;
}
else
AddNode(v,root);
}
void bsearch_tree::AddNode(double key,tnode *leaf)
{
if(key >= leaf->data)
{
if(leaf->right != NULL)
AddNode(key,leaf->right);
else
{
tnode * n = new tnode(key);
leaf->right = n;
}
}
else
{
if(leaf->left != NULL)
AddNode(key,leaf->left);
else
{
tnode * n = new tnode(key);
leaf->left = n;
}
}
}
void print(bsearch_tree tree)
{
assist(tree.root);
}
void assist(tnode *tmp)
{
if(tmp)
{
assist(tmp->left);
cout << tmp->data << endl;
assist(tmp->right);
}
}
ostream & operator << (ostream & stream,bsearch_tree const root)
{
print(root);
return stream;
}
bsearch_tree bsearch_tree::operator + (const bsearch_tree & t)
{
bsearch_tree bs;
SumTree(t.root);
return *this;
}
void bsearch_tree::SumTree(tnode *tree)
{
if(tree)
{
AddNode(tree->data,root);
SumTree(tree->left);
SumTree(tree->right);
}
}
bsearch_tree & bsearch_tree::operator = (const bsearch_tree & v)
{
if(this == &v)
return *this;
root = v.root;
return *this;
}
int main()
{
bsearch_tree bs1;
bs1.add_value(16.0);
bs1.add_value(14.0);
bs1.add_value(6.0);
bs1.add_value(18.0);
bs1.add_value(17.0);
bs1.add_value(4.0);
bs1.add_value(5.0);
bs1.add_value(1.0);
bs1.add_value(26.0);
bs1.add_value(22.0);
cout << "bs1:" << endl;
print(bs1);
bsearch_tree bs2;
bs1 = bs1 = bs1;
bs2 = bs1;
bs2.add_value(40.0);
bs2.add_value(20.0);
bs2.add_value(60.0);
cout << "cout << bs2" << endl;
cout << bs2;
bsearch_tree bs3;
//bs3 = bs1 + bs2;
bs3 = bs1;
cout << "cout << bs3" << endl;
cout << bs3;
cin.get();
return 0;
} // main
So my question is: In main function I do bsearch_tree bs1; and then I add some nodes to it, like this: bs1.add_value(16.0); then I do bsearch_tree bs2; and again I add some nodes to it.
Then I print both trees bs1 and bs2 and I find them equal which isn't right.
How do I make the add_value method to add nodes to distinct trees ?
So when I print both trees I will get different trees as the nodes I've entered are different at the first place.
Thanks
Your operator= is incorrect. You're setting a root to point to the same root of the second tree. So from the point of using this operator (e.g., in bs2 = bs1;) both of your trees address the same shared data. You need to implement the assignment operator in a way that will create a copy of the tree data.
I have a function that I am passing in a variable for; the variable, however, is a template variable. I do not know the specifics on how I am supposed to create a function with a template parameter. I do not even know if I am asking the correct question, but when I compile the program, I get the following error in the main.cpp file:
line 17 error: no matching function for call to 'BSTree<int>::BSTinsert(TNode<int>&)'
line 49 error note: candidates are: void BSTree<T>::BSTinsert(const T&) [with T = int]
I thought that I was doing everything right, but this is the one error that has hindered me from moving on. Any and all help is welcome and appreciated! (I don't think that the other two files -- treeNode.h and treeNode.cpp -- need to be shown, but I have been wrong before. If they are, lemme know and I will gladly post them. Thank you once again!
main.cpp:
#include <iostream>
#include <string>
#include "BSTree.cpp"
using namespace std;
int main()
{
BSTree<int> bt;
TNode<int> item;
for(int i=0; i<13; i++)
{
cout << "Enter value of item: ";
cin >> item;
bt.BSTinsert(item); //this is the line with the error
}
cout << "Hello world!" << endl;
return 0;
}
BSTree.h:
#ifndef BSTREE_H_INCLUDED
#define BSTREE_H_INCLUDED
#include "treeNode.cpp"
template <typename T>
class BSTree
{
TNode<T> *root;
void insert(TNode<T> * & r, const T & item);
public:
BSTree();
TNode<T>* getRoot();
void BSTinsert(const T & item);
};
#endif // BSTREE_H_INCLUDED
BSTree.cpp:
#include <iostream>
#include <string>
#include "BSTree.h"
template <typename T>
void BSTree<T>::insert(TNode<T> * & r, const T & item)
{
if(r == NULL)
TNode<T> newNode = new TNode<T>(item);
else if(r == item)
return;
else if(r->nodeValue > item)
insert(r->leftChild, item);
else if(r->nodeValue > item && r->leftChild == NULL)
{
TNode<T> newNode = new TNode<T>(item);
r->leftChild = newNode;
newNode->parent = r;
}
else if(r->nodeValue < item)
insert(r->rightChild, item);
else if(r->nodeValue < item && r->rightChild == NULL)
{
TNode<T> newNode = new TNode<T>(item);
r->rightChild = newNode;
newNode->parent = r;
}
}
template <typename T>
BSTree<T>::BSTree()
{
root = NULL;
}
template <typename T>
TNode<T>* BSTree<T>::getRoot()
{
return root;
}
template <typename T>
void BSTree<T>::BSTinsert(const T& item) //this is the line the note is referring to
{
TNode<T> tempRoot = getRoot();
insert(tempRoot, item);
}
treeNode.cpp:
#include <string>
#include <iostream>
#include "treeNode.h"
using namespace std;
template <typename T>
TNode<T>::TNode()
{
parent = NULL;
leftChild = NULL;
rightChild = NULL;
nodeValue = 0;
}
template <typename T>
TNode<T>::TNode(const T&item, TNode<T> *left, TNode<T> *right, TNode<T> *par)
{
parent = par;
leftChild = left;
rightChild = right;
nodeValue = item;
}
template <typename T>
void TNode<T>::printNodeInfo()
{
cout << "Value: " << nodeValue << endl;
if(parent != NULL)
cout << "Parent Value: " << parent << endl;
if(leftChild != NULL)
cout << "Left Child Value: " << leftChild << endl;
if(rightChild != NULL)
cout << "Right Child Value: " << rightChild << endl;
}
treeNode.h:
#ifndef TREENODE_H_INCLUDED
#define TREENODE_H_INCLUDED
template <typename T>
class TNode
{
public:
T nodeValue;
TNode<T> *leftChild, *rightChild, *parent;
TNode();
TNode(const T&item, TNode<T> *left = NULL, TNode<T> *right = NULL, TNode<T> *par = NULL);
void printNodeInfo();
friend std::istream& operator>>( std::istream& i, TNode<T>& item ){return i;}
};
#endif // TREENODE_H_INCLUDED
Does this solve your problem?
int main()
{
BSTree<int> bt;
int item;
for(int i=0; i<13; i++)
{
cout << "Enter value of item: ";
cin >> item;
bt.BSTinsert(item); //this is the line with the error
}
cout << "Hello world!" << endl;
return 0;
}