I'm writing C++ for the first time and wanted to implement a BST. I come from writing C, so I tend to write code in that way. I'm trying to wrap my head around smart pointers, but can't seem to get them to work properly. This version of the code is without any smart pointers. Any suggestions?
The C++ file:
#include <iostream>
#include "bst.h"
int main()
{
int i = 0;
BST<int> *tree = new BST<int>;
tree->addNode(new node<int>(6));
tree->addNode(new node<int>(5));
tree->addNode(new node<int>(2));
tree->addNode(new node<int>(5));
tree->addNode(new node<int>(7));
tree->addNode(new node<int>(8));
std::cout << "In order ";
tree->inOrderPrint(tree->getRoot());
std::cout << std::endl;
std::cout << "Pre order ";
tree->preOrderPrint(tree->getRoot());
std::cout << std::endl;
std::cout << "Post order ";
tree->postOrderPrint(tree->getRoot());
std::cout << std::endl;
std::cout << "Level order " << std::endl;
tree->levelOrderPrint(tree->getRoot());
std::cout << std::endl;
std::cout << "Minimum value " << tree->findMin(tree->getRoot())->getData();
std::cout << std::endl;
std::cout << "Maximum value " << tree->findMax(tree->getRoot())->getData();
std::cout << std::endl << std::endl;
std::cout << "Successor of 5: ";
if(node<int> *temp = tree->getSuccessor(tree->findNode(5)))
{
std::cout << temp->getData() << std::endl;
}
else
{
std::cout << "None" << std::endl;
}
std::cout << "Successor of 8: ";
if(node<int> *temp = tree->getSuccessor(tree->findNode(8)))
{
std::cout << temp->getData() << std::endl;
}
else
{
std::cout << "None" << std::endl;
}
std::cout << "Predecessor of 7: ";
if(node<int> *temp = tree->getPredecessor(tree->findNode(7)))
{
std::cout << temp->getData() << std::endl;
}
else
{
std::cout << "None" << std::endl << std::endl;
}
std::cout << "Predecessor of 2: ";
if(node<int> *temp = tree->getPredecessor(tree->findNode(2)))
{
std::cout << temp->getData() << std::endl;
}
else
{
std::cout << "None" << std::endl << std::endl;
}
std::cout << "Height: " << tree->getHeight(tree->getRoot()) << std::endl;
delete tree;
return 0;
}
The header file:
#define MAX(a, b) ({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a > _b ? _a : _b; })
template <typename T>
class node
{
T data;
node<T> *left;
node<T> *right;
node<T> *parent;
public:
node(T value);
~node() {};
T getData();
void updateLeft(node<T>* pointer);
void updateRight(node<T>* pointer);
void updateParent(node<T>* pointer);
node<T>* getLeft();
node<T>* getRight();
node<T>* getParent();
};
template <typename T>
node<T> :: node(T value) : parent(NULL), left(NULL), right(NULL)
{
data = value;
}
template <typename T>
T node<T> :: getData()
{
return data;
}
template <typename T>
void node<T> :: updateLeft(node<T>* pointer)
{
left = pointer;
}
template <typename T>
void node<T> :: updateRight(node<T>* pointer)
{
right = pointer;
}
template <typename T>
void node<T> :: updateParent(node<T>* pointer)
{
parent = pointer;
}
template <typename T>
node<T>* node<T> :: getLeft()
{
return left;
}
template <typename T>
node<T>* node<T> :: getRight()
{
return right;
}
template <typename T>
node<T>* node<T> :: getParent()
{
return parent;
}
template <typename T>
class BST
{
node<T> *root;
void removeNode(node<T> *delNode);
public:
BST() : root(NULL) {}
~BST();
node<T>* getRoot();
node<T>* findMin(node<T> *current);
node<T>* findMax(node<T> *current);
node<T>* findNode(T key);
node<T>* getSuccessor(node<T> *current);
node<T>* getPredecessor(node<T> *current);
bool addNode(node<T> *newNode);
void inOrderPrint(node<T> *current);
void preOrderPrint(node<T> *current);
void postOrderPrint(node<T> *current);
void levelOrderPrint(node<T> *current);
void printLevel(node<T>* current, int level);
int getHeight(node<T>* current);
};
template <typename T>
void BST<T> :: removeNode(node<T> *delNode)
{
if(delNode)
{
removeNode(delNode->getLeft());
removeNode(delNode->getRight());
delete delNode;
}
}
template <typename T>
BST<T> :: ~BST()
{
removeNode(root);
}
template <typename T>
node<T>* BST<T> :: getRoot()
{
return root;
}
template <typename T>
bool BST<T> :: addNode(node<T> *newNode)
{
if(!root)
{
root = newNode;
}
else
{
node<T> *temp = root;
node<T> *parent = NULL;
while(temp)
{
parent = std::move(temp);
if(newNode->getData() > temp->getData())
{
temp = temp->getRight();
}
else
{
temp = temp->getLeft();
}
}
if(newNode->getData() > parent->getData())
{
parent->updateRight(newNode);
}
else
{
parent->updateLeft(newNode);
}
newNode->updateParent(parent);
}
return true;
}
template <typename T>
node<T>* BST<T> :: findNode(T key)
{
node<T> *temp = root;
while(temp)
{
T data = temp->getData();
if(data == key)
{
return temp;
}
else if(data > key)
{
temp = temp->getLeft();
}
else
{
temp = temp->getRight();
}
}
return NULL;
}
template <typename T>
void BST<T> :: inOrderPrint(node<T> *current)
{
if(current)
{
inOrderPrint(current->getLeft());
std::cout << current->getData() << " ";
inOrderPrint(current->getRight());
}
}
template <typename T>
void BST<T> :: preOrderPrint(node<T> *current)
{
if(current)
{
std::cout << current->getData() << " ";
inOrderPrint(current->getLeft());
inOrderPrint(current->getRight());
}
}
template <typename T>
void BST<T> :: postOrderPrint(node<T> *current)
{
if(current)
{
inOrderPrint(current->getLeft());
inOrderPrint(current->getRight());
std::cout << current->getData() << " ";
}
}
template <typename T>
void BST<T> :: printLevel(node<T>* current, int level)
{
if(current)
{
if(level == 0)
{
std::cout << current->getData() << " ";
}
else
{
printLevel(current->getLeft(), level-1);
printLevel(current->getRight(), level-1);
}
}
}
template <typename T>
void BST<T> :: levelOrderPrint(node<T> *current)
{
int height = getHeight(current);
for(int level = 0; level < height; level++)
{
printLevel(current, level);
std::cout << std::endl;
}
}
template <typename T>
node<T>* BST<T> :: findMin(node<T> *current)
{
node<T> *temp = current;
node<T> *prev;
while(temp)
{
prev = temp;
temp = temp->getLeft();
}
return prev;
}
template <typename T>
node<T>* BST<T> :: findMax(node<T> *current)
{
node<T> *temp = root;
node<T> *prev;
while(temp)
{
prev = temp;
temp = temp->getRight();
}
return prev;
}
template <typename T>
node<T>* BST<T> :: getSuccessor(node<T> *current)
{
if(current->getRight())
{
return findMin(current->getRight());
}
node<T> *parent = current->getParent();
while(parent && current == parent->getRight())
{
current = parent;
parent = parent->getParent();
}
return parent;
}
template <typename T>
node<T>* BST<T> :: getPredecessor(node<T> *current)
{
if(current->getLeft())
{
return findMax(current->getLeft());
}
node<T> *parent = current->getParent();
while(parent && current == parent->getLeft())
{
current = parent;
parent = parent->getParent();
}
return parent;
}
template <typename T>
int BST<T> :: getHeight(node<T> *current)
{
int max = 0;
if(!current)
{
return 0;
}
max = MAX(getHeight(current->getLeft()), getHeight(current->getRight()));
return (1 + max);
}