The Tree template example program consists of three files:
#include <iostream> using namespace std; template <class T> class Tree { private: T data; Tree* left = nullptr; // 1 Tree* right = nullptr; public: //Tree() : left(nullptr), right(nullptr) {} // 2 ~Tree(); T* insert(T& data); T* search(T& data); void list() { right->_list(); } // 3 private: void _list(); // 4 };
template <class T> Tree<T>::~Tree() { if (left != nullptr) delete left; if (right != nullptr) delete right; }
delete left
and delete right
each trigger a recursive call to the destructor function.
template <class T> T* Tree<T>::insert(T& data) { Tree* root = this; // 1 Tree* down = right; while (down != nullptr && !(down->data == data)) // 2 { root = down; if (data < down->data) down = down->left; else down = down->right; } if (down != nullptr) // 3 return &down->data; down = new Tree; // 4 down->data = data; if (data < root->data) // 5 root->left = down; else root->right = down; return &down->data; // 6 }
operator<
and operator==
are implemented for the class that replaces the template variable T.
operator==
than it is is to implement operator!=
, so the equality operator is used here with the negation operator ( !
)template <class T> T* Tree<T>::search(T& data) { Tree* root = right; // 1 while (root != nullptr && !(root->data == data)) // 2 { if (data < root->data) root = root->left; else root = root->right; } if (root == nullptr) // 3 return nullptr; else return &root->data; }
nullptr
.
template <class T> void Tree<T>::_list() { if (left != nullptr) left->_list(); cout << data << endl; if (right != nullptr) right->_list(); }
operator<<
is overloaded for the template class that replaces T.
#include <iostream> #include <string> using namespace std; class Employee { private: string name; int id; public: Employee(string n = "", int en = 0) : name(n), id(en) {} bool operator==(Employee& e) { return name == e.name; } // 1 bool operator<(Employee& e) { return name < e.name; } // 2 friend ostream& operator<<(ostream& out, Employee& me) // 3 { out << me.name << " " << me.id; return out; } };
#include <iostream> #include <string> #include "Tree.h" #include "Employee.h" using namespace std; int main() { Tree<Employee> tree; string name; while (true) { cout << "N\tEnter a new Employee" << endl; cout << "S\tSearch for an Employee" << endl; cout << "L\tList all Employees" << endl; cout << "E\tExit" << endl; cout << "Operation: "; char operation; cin >> operation; cin.ignore(); switch (operation) { case 'N' // create a new Employee and insert it into the Tree case 'n': { cout << "Employee name: "; getline(cin, name); int number; cout << "Employee Number: "; cin >> number; cin.ignore(); Employee employee(name, number); // Data tree.insert(employee); break; } case 'S': // search for an exiting Employee in the Tree case 's': { cout << "Employee name: "; getline(cin, name); Employee employee(name); Employee* e = tree.search(employee); if (e != nullptr) cout << "Employee: " << *e << endl; else cout << name << " NOT FOUND" << endl; break; } case 'L': // list all of the Employees in the Tree case 'l': tree.list(); break; case 'E': // exit the program case 'e': return 0; //exit(0); // ends the program but doesn't call the destructor default: cerr << "Unrecognized operation: \"" << operation << "\"" << endl; break; } } return 0; }