//************************ BST.h ************************** // simplified version of text binary search tree #include using namespace std; #ifndef BINARY_SEARCH_TREE #define BINARY_SEARCH_TREE template class BSTNode { public: BSTNode() { left = right = 0; } BSTNode(const T& el, BSTNode *l = 0, BSTNode *r = 0) { key = el; left = l; right = r; } T key; BSTNode *left, *right; }; template class BST { public: BST() { root = 0; } ~BST() { clear(); } void clear() { clear(root); root = 0; } bool isEmpty() const { return root == 0; } void snapShot(ostream& out) { out << "TreeForm["; snapShot(out,root); out << ']' << endl; } void preorder() { preorder(root); } void inorder() { inorder(root); } void postorder() { postorder(root); } void insert(const T&); T* search(const T& el) const { return search(root,el); } void deleteByCopying(BSTNode*&); void findAndDeleteByCopying(const T&); void deleteByMerging(BSTNode*&); void findAndDeleteByMerging(const T&); protected: BSTNode* root; void clear(BSTNode*); T* search(BSTNode*, const T&) const; void preorder(BSTNode*); void inorder(BSTNode*); void postorder(BSTNode*); void snapShot(ostream& out,BSTNode*); void visit(BSTNode* p) { cout << p->key << ' '; } }; template void BST::clear(BSTNode *p) { if (p != 0) { clear(p->left); clear(p->right); delete p; } } template void BST::insert(const T& el) { BSTNode *p = root, *prev = 0; while (p != 0) { // find a place for inserting new node; prev = p; if (p->key < el) p = p->right; else p = p->left; } if (root == 0) // tree is empty; root = new BSTNode(el); else if (prev->key < el) prev->right = new BSTNode(el); else prev->left = new BSTNode(el); } template T* BST::search(BSTNode* p, const T& el) const { while (p != 0) if (el == p->key) return &p->key; else if (el < p->key) p = p->left; else p = p->right; return 0; } template void BST::inorder(BSTNode *p) { if (p != 0) { inorder(p->left); visit(p); inorder(p->right); } } template void BST::preorder(BSTNode *p) { if (p != 0) { visit(p); preorder(p->left); preorder(p->right); } } template void BST::postorder(BSTNode* p) { if (p != 0) { postorder(p->left); postorder(p->right); visit(p); } } template void BST::snapShot(ostream& out,BSTNode *p) { out << '\"' << p->key << '\"'; if(p->left != 0 || p->right != 0) { out << '['; if(p->left==0) out << "\"\""; else snapShot(out,p->left); out << ','; if(p->right==0) out << "\"\""; else snapShot(out,p->right); out << ']'; } } template void BST::deleteByCopying(BSTNode*& node) { BSTNode *previous, *tmp = node; if (node->right == 0) // node has no right child; node = node->left; else if (node->left == 0) // node has no left child; node = node->right; else { tmp = node->left; // node has both children; previous = node; // 1. while (tmp->right != 0) { // 2. previous = tmp; tmp = tmp->right; } node->key = tmp->key; // 3. if (previous == node) previous->left = tmp->left; else previous->right = tmp->left; // 4. } delete tmp; // 5. } // findAndDeleteByCopying() searches the tree to locate the node containing // el. If the node is located, the function DeleteByCopying() is called. template void BST::findAndDeleteByCopying(const T& el) { BSTNode *p = root, *prev = 0; while (p != 0 && !(p->key == el)) { prev = p; if (p->key < el) p = p->right; else p = p->left; } if (p != 0 && p->key == el) if (p == root) deleteByCopying(root); else if (prev->left == p) deleteByCopying(prev->left); else deleteByCopying(prev->right); else if (root != 0) cout << "key " << el << " is not in the tree\n"; else cout << "the tree is empty\n"; } template void BST::deleteByMerging(BSTNode*& node) { BSTNode *tmp = node; if (node != 0) { if (!node->right) // node has no right child: its left node = node->left; // child (if any) is attached to its parent; else if (node->left == 0) // node has no left child: its right node = node->right; // child is attached to its parent; else { // be ready for merging subtrees; tmp = node->left; // 1. move left while (tmp->right != 0)// 2. and then right as far as possible; tmp = tmp->right; tmp->right = // 3. establish the link between the node->right; // the rightmost node of the left // subtree and the right subtree; tmp = node; // 4. node = node->left; // 5. } delete tmp; // 6. } } template void BST::findAndDeleteByMerging(const T& el) { BSTNode *node = root, *prev = 0; while (node != 0) { if (node->key == el) break; prev = node; if (node->key < el) node = node->right; else node = node->left; } if (node != 0 && node->key == el) if (node == root) deleteByMerging(root); else if (prev->left == node) deleteByMerging(prev->left); else deleteByMerging(prev->right); else if (root != 0) cout << "key " << el << " is not in the tree\n"; else cout << "the tree is empty\n"; } #endif