BST.h:
#ifndef BST_H_
#define BST_H_ 1
#include <iostream>
#include <stdio.h>
#include <string>
#include <vector>
class Node {
public:
int num;
Node * previous;
Node * next;
Node() {this->num = 0; this->previous = NULL; this->next = NULL;}
~Node() {delete previous; delete next;}
friend class BSTree;
};
class BSTreeNode {
private:
BSTreeNode(const int & newDataItem, const int & newKey, BSTreeNode * leftPtr, BSTreeNode * rightPtr);
~BSTreeNode() { delete left; delete right; }
BSTreeNode * remove(int, BSTreeNode *);
int subtreeminKey();
int key;
int dataItem;
BSTreeNode * left;
BSTreeNode * right;
friend class BSTree;
};
class BSTree {
private:
void showSub(BSTreeNode *p, int level) const;
BSTreeNode * root;
public:
BSTree();
~BSTree();
void insert(const int & newDataItem, const int & newKey);
bool retrieve(int searchKey, int & searchDataItem) const;
bool remove(int deleteKey);
void writeKeys() const;
void clear();
bool isEmpty() const;
void printT() const;
void printTree(BSTreeNode *) const;
bool isBalanced(BSTreeNode * pRoot); // determine whether the tree is balanced or not
bool isBalanced();
int TreeDepth(BSTreeNode * pRoot); // calculate the depth of the tree (or subtree)
int TreeDepth();
void sumPath(int sum, int ¤tSum, std::vector<int>& v);
void psumPath(int expectedSum, int ¤tSum, std::vector<int>& v, BSTreeNode *current);
void toInorderLinkedList(Node * head, Node *& tail);
void toInorderLinkedList(Node * head, Node * &tail, BSTreeNode * pRoot);
bool findPath(int num, std::vector<int> &v);
bool findPath(BSTreeNode *pRoot, int num, std::vector<int> &v);
void mirror();
void mirror(BSTreeNode *pRoot);
bool isPostOrder(const std::vector<int> &v);
bool isPostOrder(const int arr[], int len);
};
void printList(Node * head);
#endif
BST.cpp:
#include "BST.h"
using namespace std;
BSTreeNode::BSTreeNode(const int & newDataItem, const int & newKey, BSTreeNode * leftPtr, BSTreeNode * rightPtr)
{
key = newKey;
dataItem = newDataItem;
left = leftPtr;
right = rightPtr;
}
BSTree::BSTree() {
root = NULL;
}
BSTree::~BSTree() {
delete root;
}
void BSTree::insert(const int & newDataItem, const int & newKey) {
BSTreeNode *newNode = new BSTreeNode(newDataItem, newKey, NULL, NULL);
if(root == NULL)
root = newNode;
else {
BSTreeNode *current = root;
while(current != 0) {
if(newNode->key < current->key) {
if(current->left != 0)
current = current->left;
else {
current->left = newNode;
break;
}
} else if(newNode->key > current->key) {
if(current->right != 0)
current = current->right;
else {
current->right = newNode;
break;
}
}
}
}
}
bool BSTree::retrieve(int searchKey, int & searchDataItem) const {
if(root == NULL)
return false;
else {
BSTreeNode *current = root;
while(current != 0) {
if(current->key == searchKey) {
searchDataItem = current->dataItem;
return true;
} else if(current->key > searchKey) {
if(current->left != NULL)
current = current->left;
else
return false;
} else {
if(current->right != NULL)
current = current->right;
else
return false;
}
}
}
}
bool BSTree::remove(int deleteKey) {
if(root == NULL) {
return false;
} else {
if(root->key == deleteKey) {
BSTreeNode *header = new BSTreeNode(0, 0, NULL, NULL);
header->left = root; // now the root is the left child of header
BSTreeNode *remove = root->remove(root->key, header);
root = header->left;
delete remove;
return true;
} else {
BSTreeNode *remove = root->remove(deleteKey, NULL);
if(remove != NULL) {
delete remove;
return true;
} else
return false;
}
}
}
BSTreeNode * BSTreeNode::remove(int deleteKey, BSTreeNode * parent) {
if(this->key == deleteKey) {
if(right != NULL && left != NULL) {
this->key = right->subtreeminKey();
return right->remove(this->key, this);
} else if(parent->right == this) {
parent->right = (left == NULL) ? right:left;
return this;
} else if(parent->left == this) {
parent->left = (left == NULL) ? right:left;
return this;
}
} else if(this->key < deleteKey) {
if(right != NULL) {
return right->remove(deleteKey, this);
} else {
return NULL;
}
} else if(this->key > deleteKey) {
if(left != NULL)
return left->remove(deleteKey, this);
else
return NULL;
}
}
bool BSTree::isEmpty() const {
return root == NULL;
}
void BSTree::printT() const {
printTree(root);
}
void BSTree::printTree(BSTreeNode *current) const {
if(current != NULL) {
cout << current->key ;
cout << ",(";
printTree(current->left);
cout << "),(";
printTree(current->right);
cout << ")";
}
}
int BSTreeNode::subtreeminKey() {
if(left == NULL)
return this->key;
else
return left->subtreeminKey();
}
bool BSTree::isBalanced(BSTreeNode * pRoot) {
if(!pRoot)
return false;
int leftDepth = TreeDepth(pRoot->left);
int rightDepth = TreeDepth(pRoot->right);
if((leftDepth - rightDepth) > 1 || (leftDepth - rightDepth) < -1)
return false;
else
return true;
return isBalanced(pRoot->left) && isBalanced(pRoot->right);
}
int BSTree::TreeDepth(BSTreeNode * pRoot) {
if(!pRoot)
return 0;
if(pRoot->left == NULL && pRoot->right == NULL)
return 0;
int leftDepth = TreeDepth(pRoot->left);
int rightDepth = TreeDepth(pRoot->right);
return (leftDepth>rightDepth)?(leftDepth+1):(rightDepth+1);
}
bool BSTree::isBalanced() {
return isBalanced(root);
}
/*
bool BSTree::isBalanced(BSTreeNode * pRoot) {
if(!pRoot)
return false;
int lh = TreeDepth(pRoot->left);
int rh = TreeDepth(pRoot->right);
if(abs(lh-rh) <= 1)
return true;
else
return false;
return (isBalanced(pRoot->left) && isBalanced(pRoot->right));
}
*/
int BSTree::TreeDepth() {
return TreeDepth(root);
}
void BSTree::sumPath(int sum, int ¤tSum, std::vector<int>& v) {
psumPath(sum, currentSum, v, root);
}
// DFS is Backtracking
void BSTree::psumPath(int expectedSum, int ¤tSum, std::vector<int>& v, BSTreeNode *current) {
if(!current)
return;
bool isLeaf = (current->left == NULL) && (current->right == NULL);
currentSum += current->dataItem;
v.push_back(current->dataItem);
if(isLeaf && currentSum == expectedSum) {
std::cout << endl;
for(vector<int>::iterator it = v.begin(); it != v.end(); it++) {
std::cout << *it << "\t";
}
}
psumPath(expectedSum, currentSum, v, current->left);
psumPath(expectedSum, currentSum, v, current->right);
currentSum -= current->dataItem;
v.pop_back();
}
/*
void pSumPath(int expectedSum, int currentSum, vector<int> &v, BSTreeNode * pRoot) {
if(!pRoot) return;
bool isLeaf = (pRoot->left == NULL) && (pRoot->right == NULL);
v.push_back(pRoot->dataItem);
currentSum += pRoot->dataItem;
if(isLeaf && currentSum==expectedSum) {
std::cout << endl;
for(vector<int>::iterator it = v.begin(); it!=v.end(); it++)
std::cout << *it << "\t";
return;
}
pSumPath(expectedSum, currentSum, v, pRoot->left);
pSumPath(expectedSum, currentSum, v, pRoot->right);
currentSum -= pRoot->dataItem;
v.pop_back();
}
*/
void BSTree::toInorderLinkedList(Node * head, Node *&tail) {
toInorderLinkedList(head, tail, root);
}
// Here in order to maintain tail, it need to transfer into a reference
void BSTree::toInorderLinkedList(Node * head, Node * &tail, BSTreeNode * current) {
if(!head || !current)
return;
if(current->left != NULL)
toInorderLinkedList(head, tail, current->left);
Node * newNode = new Node();
newNode->num = current->dataItem;
tail->next = newNode;
newNode->previous = tail;
tail = newNode;
if(current->right != NULL)
toInorderLinkedList(head, tail, current->right);
}
void printList(Node * head) {
Node * p = head->next;
std::cout << "\nThe Linked List is:\n";
while(p!=NULL) {
std::cout << p->num << "\t";
p = p->next;
}
cout << endl;
}
bool BSTree::findPath(int num, std::vector<int> &v) {
return findPath(root, num, v);
}
/*
bool BSTree::findPath(BSTreeNode *pRoot, int num) {
if(!pRoot)
return false;
bool isLeaf = (pRoot->left == NULL) && (pRoot->right == NULL);
if(pRoot->dataItem > num)
return false;
if((pRoot->dataItem == num) && isLeaf)
return true;
bool flag1 = findPath(pRoot->left, num - pRoot->dataItem), flag2 = findPath(pRoot->right, num - pRoot->dataItem);
return flag1 || flag2;
}
*/
bool BSTree::findPath(BSTreeNode* pRoot, int num, std::vector<int> &v) {
if(!pRoot)
return false;
v.push_back(pRoot->dataItem);
if(pRoot->dataItem == num) {
return true;
}
bool l = findPath(pRoot->left, num, v);
bool r = findPath(pRoot->right, num, v);
if(!l && !r)
v.pop_back();
return l || r;
}
/*
bool BSTree::findPath(BSTreeNode* pRoot, int num, std::vector<int> &v) {
if(!pRoot) return false;
v.push_back(pRoot->dataItem);
if(pRoot->dataItem == num)
return true;
bool l = findPath(pRoot->left, num, v);
bool r = findPath(pRoot->right, num, v);
if(!l && !r)
v.pop_back();
return l||r;
}
*/
void BSTree::mirror() {
mirror(root);
}
void BSTree::mirror(BSTreeNode *pRoot) {
if(!pRoot)
return;
BSTreeNode * tmp = pRoot->left;
pRoot->left = pRoot->right;
pRoot->right = tmp;
if(pRoot->left != NULL)
mirror(pRoot->left);
if(pRoot->right != NULL)
mirror(pRoot->right);
}
bool BSTree::isPostOrder(const std::vector<int> &v) {
int len = v.size();
if(len <= 2)
return true;
std::vector<int> leftPart;
std::vector<int> rightPart;
int tmp = v[len-1];
int i = 0;
while(i<len-1) {
if(v[i] >= tmp)
break;
leftPart.push_back(v[i]);
i++;
}
if(i == len-1) {
return true;
} else {
for(int j = i; j < len-1; j++) {
if(v[j] < tmp)
return false;
rightPart.push_back(v[j]);
}
}
return isPostOrder(leftPart) && isPostOrder(rightPart);
}
bool isPostOrder(const int arr[], int len) {
if(len <= 2)
return true;
int tmp = arr[len-1];
int i = 0;
while(i < len-1) {
if(arr[i] > tmp)
break;
i++;
}
int j = i;
while(j < len-1) {
if(arr[j] < tmp)
return false;
j++;
}
return isPostOrder(arr, i) && isPostOrder(arr+i, j-i);
}
BSTApp.cpp:
#include "BST.h"
using namespace std;
int main() {
BSTree bst;
int item = 3;
int key = 3;
bst.insert(item, key);
item = 1;
key = 1;
bst.insert(item, key);
item = 9;
key = 9;
bst.insert(item, key);
item = 5;
key = 5;
bst.insert(item, key);
item = 42;
key = 42;
bst.insert(item, key);
item = 45;
key = 45;
bst.insert(item, key);
// bst.remove(3);
bst.printT();
int skey = 42;
int sdata = 0;
cout << endl << bst.retrieve(skey, sdata) << endl;
cout << sdata << endl;
cout << bst.TreeDepth() << endl;
cout << bst.isBalanced() << endl;
std::vector<int> v;
int sum = 17;
int currentSum = 0;
bst.sumPath(sum, currentSum, v);
Node * head = new Node();
Node * tail = head;
bst.toInorderLinkedList(head, tail);
printList(head);
std::vector<int> v2;
bst.findPath(42, v2);
std::cout << endl;
for(std::vector<int>::iterator it = v2.begin(); it != v2.end(); it++)
std::cout << *it << "\t";
return 0;
}