dsa-practice/libs/dope/bintree.hpp

173 lines
3.7 KiB
C++

#pragma once
#include <queue>
template <class T>
class DopeBinTreeNode{
DopeBinTreeNode<T>* left;
DopeBinTreeNode<T>* right;
T data;
public:
DopeBinTreeNode(T data);
~DopeBinTreeNode();
void SetLeft(DopeBinTreeNode<T>* newleft){left = newleft;}
void SetRight(DopeBinTreeNode<T>* newright){right = newright;}
DopeBinTreeNode<T>* GetLeft(){return left;}
DopeBinTreeNode<T>* GetRight(){return right;}
T GetData(){return data;}
};
template <class T>
class DopeBinTree{
DopeBinTreeNode<T>* root;
T* RecPreOrderTraversal(DopeBinTreeNode<T>* node, T* out);
T* RecInOrderTraversal(DopeBinTreeNode<T>* node, T* out);
T* RecPostOrderTraversal(DopeBinTreeNode<T>* node, T* out);
public:
DopeBinTree(T data);
DopeBinTree();
~DopeBinTree();
void insert(T data);
bool isEmpty();
DopeBinTreeNode<T>* getRoot(){return root;}
void RecPreOrderTraversalArray(T* array);
void RecInOrderTraversalArray(T* array);
void RecPostOrderTraversalArray(T* array);
};
// Implementations ___________________________________________________
template <class T>
DopeBinTreeNode<T>::DopeBinTreeNode(T node_data):
left(nullptr),
right(nullptr),
data(node_data)
{
}
template <class T>
DopeBinTreeNode<T>::~DopeBinTreeNode(){
delete left;
delete right;
}
template <class T>
DopeBinTree<T>::DopeBinTree(T data){
root = new DopeBinTreeNode<T>(data);
}
template <class T>
DopeBinTree<T>::DopeBinTree():
root(nullptr)
{
}
template <class T>
DopeBinTree<T>::~DopeBinTree(){
if (root != nullptr){
delete root;
}
}
template <class T>
// Insert Breadth first
void DopeBinTree<T>::insert(T data){
DopeBinTreeNode<T>* current_node = root;
if (root == nullptr){
root = new DopeBinTreeNode<T>(data);
} else {
auto new_node = new DopeBinTreeNode<T>(data);
// Breadth first traversal
std::queue<DopeBinTreeNode<T>*> q;
q.push(root);
while(!q.empty()){
current_node = q.front();
q.pop();
if(current_node->GetLeft()){
q.push(current_node->GetLeft());
} else {
current_node->SetLeft(new_node);
break;
}
if(current_node->GetRight()){
q.push(current_node->GetRight());
} else {
current_node->SetRight(new_node);
break;
}
}
}
}
template <class T>
bool DopeBinTree<T>::isEmpty(){
if(root == nullptr){
return true;
} else {
return false;
}
}
template <class T>
T* DopeBinTree<T>::RecPreOrderTraversal(DopeBinTreeNode<T>* node, T* out){
if (node == nullptr){
return out--;
}
*out = node->GetData();
out++;
out = RecPreOrderTraversal(node->GetLeft(), out);
out = RecPreOrderTraversal(node->GetRight(), out);
return out;
}
template <class T>
T* DopeBinTree<T>::RecInOrderTraversal(DopeBinTreeNode<T>* node, T* out){
if (node == nullptr){
return out--;
}
out = RecInOrderTraversal(node->GetLeft(), out);
*out = node->GetData();
out++;
out = RecInOrderTraversal(node->GetRight(), out);
return out;
}
template <class T>
T* DopeBinTree<T>::RecPostOrderTraversal(DopeBinTreeNode<T>* node, T* out){
if (node == nullptr){
return out--;
}
out = RecPostOrderTraversal(node->GetLeft(), out);
out = RecPostOrderTraversal(node->GetRight(), out);
*out = node->GetData();
out++;
return out;
}
template <class T>
void DopeBinTree<T>::RecPreOrderTraversalArray(T* array){
int index = 0;
DopeBinTreeNode<T>* node = root;
RecPreOrderTraversal(node, &array[index]);
}
template <class T>
void DopeBinTree<T>::RecInOrderTraversalArray(T* array){
int index = 0;
DopeBinTreeNode<T>* node = root;
RecInOrderTraversal(node, &array[index]);
}
template <class T>
void DopeBinTree<T>::RecPostOrderTraversalArray(T* array){
int index = 0;
DopeBinTreeNode<T>* node = root;
RecPostOrderTraversal(node, &array[index]);
}