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
|