Binary Search Tree-used with user defined class

I am working on a program that uses a class I created called Student. I want to be able to add different students to a Binary Search Tree, and use the student's gpa (grade point average) to compare students with each other and place them in the correct location in the Tree.

Student class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#ifndef STUDENT_H
#define STUDENT_H

#include <string>
#include <iostream>
#include <iomanip>

class Student{
	friend ostream& operator<<(ostream& out, const Student& stu);
public:
	Student();
	Student(string name, int id, double gpa);
	//double getGpa() const;

	int compare(const Student& right) const;

	//char& operator[](int pos);
	//const char& operator[](int pos) const;

	bool operator==(const Student& right) const;
	bool operator<(const Student& right) const;
	bool operator>(const Student& right) const;
private:
	string name;
	int id;
	double gpa;
};

Student::Student(){
	name = "unkown";
	id = 0;
	gpa = 0;
}

Student::Student(string name, int id, double gpa){
	this->name = name;
	this->id = id;
	this->gpa = gpa;
}

//double Student::getGpa() const{
//	return gpa;
//}

int Student::compare(const Student& right) const{
	return gpa - right.gpa;
}

bool Student::operator==(const Student& right) const{
	if(compare(right) == 0){
		return true;
	}
	return false;
}

bool Student::operator<(const Student& right) const{
	if(compare(right) < 0){
		return true;
	}
	return false;
}

bool Student::operator>(const Student& right) const{
	if(compare(right) > 0){
		return true;
	}
	return false;
}

ostream& operator<<(ostream& out, const Student& stu){
	out <<"Name: " << setw(10) << stu.name 
		<< " id: " << setw(3) << stu.id 
		<< " gpa: " << setw(3) << stu.gpa;
	return out;
}
#endif 


tree node (TNode) class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#ifndef TNODE_H
#define TNODE_H

template <typename T> class BST;

template <typename T>
class TNode{
public:
	TNode(T data);
	virtual ~TNode();

	friend class BST<T>;
private:
	TNode* right;
	TNode* left;
	T data;
};

template <typename T>
TNode<T>::TNode(T data){
	this->data = data;
	right = left = NULL;
}

template <typename T>
TNode<T>::~TNode(){
}
#endif 




Sorry, but my message length was too long. So I am going to have to separate into pieces.
This is my Binary Search Tree (BST) class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
#ifndef BST_H
#define BST_H

#include <iostream>
#include <cstdlib>
#include <new>

template <typename T>
class BST{
public:
	BST();
	virtual ~BST();

	//Member functions used by client program
	//Check the difference between public and corresponding private function call
	//in terms of their signatures
	void insert(T data){
		root = insert(data, root);
	}

	void remove(T data){
		root = remove(data, root);
	}

	bool search(T data){
		return search(root, data);
	}

	//Tree Traversal
	void inOrder(void (*visit)(T)){
		inOrder(root, visit);
	}

	void preOrder(void (*visit)(T)){
		preOrder(root, visit);
	}

	void postOrder(void (*visit)(T)){
		postOrder(root, visit);
	}

	//Get the node count
	int getNodeCount(){
		return getNodeCount(root);
	}
	//Get the height
	int getHeight(){
		return getHeight(root);
	}
	//Get the leaf count
	int getLeafCount(){
		return getLeafCount(root);
	}

	T findSuccessor(){
		return findSuccessor(root)->data;
	}
private:
	TNode<T>* root;

	TNode<T>* insert(T data, TNode<T>* r);
	TNode<T>* remove(T data, TNode<T>* r);
	void inOrder(TNode<T>* r, void (*visit)(T));
	void preOrder(TNode<T>* r, void (*visit)(T));
	void postOrder(TNode<T>* r, void (*visit)(T));
	bool search(TNode<T>* r, T data);
	int getNodeCount(TNode<T>* r);
	int getLeafCount(TNode<T>* r);
	int getHeight(TNode<T>* r);
	TNode<T>* findSuccessor(TNode<T>* r);
	void deleteTree(TNode<T>* r);
};

template <typename T>
BST<T>::BST(){
	root = NULL;
}

template <typename T>
BST<T>::~BST(){
	if(root != NULL)
		deleteTree(root);

	root = NULL;
}

template <typename T>
void BST<T>::deleteTree(TNode<T>* rt){
	if(rt){
		deleteTree(rt->left);
		deleteTree(rt->right);
		delete rt;
	}
}

template <typename T>
TNode<T>* BST<T>::insert(T data, TNode<T>* rt){
	try{
		if(rt == NULL){
			rt = new TNode<T>(data);
		}
		else if(data < rt->data){
			rt->left = insert(data, rt->left);
		}
		else if(data > rt->data){
			rt->right = insert(data, rt->right);
		}
		return rt;
	}
	catch(bad_alloc &e){
		std::cout << "mem allocation exception: " << e.what() << endl;
		exit(1);
	}
}

template <typename T>
TNode<T>* BST<T>::remove(T data, TNode<T>* rt){
	if(rt == NULL)
		return rt;

	if(data < rt->data){
		rt->left = remove(data, rt->left);
	}
	else if(data > rt->data){
		rt->right = remove(data, rt->right);
	}
	else if(rt->left !=NULL && rt->right != NULL){
		// Two children exist
		// step1: findSuccessor is to find the successor node
		T minData = findSuccessor(rt->right)->data;
		
		// step2: replace the data
		rt->data = minData;
		
		//step3: remove the successor node by using recursion
		//       passing rt->right as the tree root
		//       so that the successor node can be deleted
		rt->right = remove(minData, rt->right);
	}
	else{
		// only one child exists or no children
		
		TNode<T>* discard = rt;

		//if rt->left != NULL, i.e the only one child is the left 
		//    then  rt = rt->left, i.e making the left subtree to rt 
		//if rt->>left != NULL, i.e the only one child should be the right or no children 
		//    then rt = rt->right.  This makes two subcases
		//	       c1) if rt->right is NULL, no children and rt = NULL	
		//         c2) if rt->right is not NULL, the right is the only child, making the right subtree to rt
		rt = (rt->left != NULL) ? rt->left : rt->right;

		delete discard;
	}
	return rt;
}

template <typename T>
void BST<T>::inOrder(TNode<T>* rt, void (*visit)(T)){
	if(rt != 0){
		inOrder(rt->left, visit);
		(*visit)(rt->data);
		inOrder(rt->right, visit);
	}
}

template <typename T>
void BST<T>::preOrder(TNode<T>* rt, void (*visit)(T)){
	if(rt != 0){
		(*visit)(rt->data);
		inOrder(rt->left, visit);
		inOrder(rt->right, visit);
	}
}

template <typename T>
void BST<T>::postOrder(TNode<T>* rt, void (*visit)(T)){
	if(rt != 0){
		inOrder(rt->left, visit);
		inOrder(rt->right, visit);
		(*visit)(rt->data);
	}
}

//private: search data in the BST with rt as root
template <typename T>
bool BST<T>::search(TNode<T>* rt, T data){
	if(rt == NULL) return false;
	else if(rt->data == data) return true;
	else if(data < rt->data)
		return search(rt->left, data);
	else
		return search(rt->right, data);
}

template <typename T>
int BST<T>::getNodeCount(TNode<T>* rt){
	if(rt == NULL) return 0;
	return getNodeCount(rt->left) + getNodeCount(rt->right) +  1;
}

template <typename T>
int BST<T>::getHeight(TNode<T>* rt){
	if(rt == NULL) return 0;
	else if(rt->left == NULL && rt->right == NULL) return 1;
	else{
		int rh = getHeight(rt->right);
		int lh = getHeight(rt->left);
		return rh > lh ? rh+1 : lh+1;
	}
}

template <typename T>
int BST<T>::getLeafCount(TNode<T>* rt){
	if(rt == NULL) return 0;
	else if(rt->left == NULL && rt->right == NULL){
		return 1;
	}
	else return getLeafCount(rt->left) + getLeafCount(rt->right);
}

//findSuccessor is written as a recursive function to practice recursion
//You can change this function with a loop, making it iterative
//Note: the return type is a node pointer
template <typename T>
TNode<T>* BST<T>::findSuccessor(TNode<T>* rt){
	if(rt->left == NULL)
		return rt;
	else
		return findSuccessor(rt->left);
}
#endif 


main.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
#include <ctime>
#include <string>
using namespace std;

#include "TNode.h"
#include "BST.h"
#include "Student.h"

template <typename T>
void visit(T data);

int main()
{
	//BST Student test---------
	cout << "\n*** Binary Search Tree Test: Student ***" << endl;
	BST<Student> tree1;

	string nameArr[] = {"Lee", "Washington", "Abrams", "Pershing", "MacArthur", "Bradley", "Patton", "Eisenhower", "Grant", "Powell"};
	int idArr[] = {123, 234, 345, 456, 567, 678, 789, 890, 901, 012};
	double gpaArr[] = {3.2, 2.8, 3.1, 3.0, 3.4, 3.6, 3.5, 4.0, 3.3, 3.8};

	Student stu[10];

	for(int i = 0; i < 10; i++){
		Student s(nameArr[i], idArr[i], gpaArr[i]);
		stu[i] = s;
	}

	for(int i = 0; i < 10; i++){
		tree1.insert(stu[i]);
	}

	cout << "\ninOrder:" << endl;
	tree1.inOrder(visit);

	cout << "\n# of nodes = " << tree1.getNodeCount() << endl;

	return 0;
}

template <typename T>
void visit(T data){
	cout << data << endl;
}


Here is the output I get:

*** Binary Search Tree Test: Student ***

inOrder:
Name:        Lee id: 123 gpa: 3.2

# of nodes = 1
What I would like to have is the full list of 10 students in the tree. I think my problem is occurring in my BST.h file when the insert function is called or my Student.h file with my overloaded operators. I am guessing that in the insert function it is looking at the rt (root node) and not comparing students correctly so it steps out of the else if clauses and returns the root node, thus only giving me the first student that was entered into the Binary Search Tree.

Sorry if this is too wordy, but I want to make sure that I am being as clear as possible.
Okay, well I took a break and it seems the problem lies within my overloaded operators as I guessed.
Topic archived. No new replies allowed.