// File: BinarySearchTree.cpp // Binary Tree ADT implemented with TreeNode linked structures #include #include #include #include "BinarySearchTree.h" using namespace std; // Constructor template BinaryTree::BinaryTree() {root=NULL;} // Place Element into Tree // Returns 1 if inserted, 0 if data already in tree template int BinaryTree::insertToTree(const treeEltType &data) {if (root==NULL) { // Empty Tree root=new TreeNode(data); return(1); } // Search for spot to put data; We only stop when we get to the bottom (NULL) TreeNode *t=root,*parent; while(t!=NULL) { if (t->info==data) // data already in Tree return(0); parent=t; // Set the trail pointer to the ancestor of where we're going if (datainfo) t=t->left; else t=t->right; } // Found the spot; insert node. if (datainfo) parent->left=new TreeNode(data); else parent->right=new TreeNode(data); return(1); } // Search for Element in Tree // Assumes == is defined for treeEltType // Returns Ptr to Elt if Found, NULL otherwise template bool BinaryTree::treeSearch(const treeEltType &key) {TreeNode *t=root; while (t && t->info != key) if (key < t->info) t=t->left; else t=t->right; return(t); // auto convert int to bool } // Retrieve Element from Tree (leaving Tree Intact) // Precondition: Item is in Tree template treeEltType &BinaryTree::retrieveFromTree(const treeEltType &key) {TreeNode *t; for (t=root;t->info!=key;) if (keyinfo) t=t->left; else t=t->right; return(t->info); } // Remove an Element from the tree // Precondition: Element is in the Tree; template void BinaryTree::deleteFromTree(const treeEltType &data) {TreeNode *nodeWithData,*nodeToDelete,*t=root,*trailT=NULL; // Find spot while (t->info!=data) { // safe because of precondition trailT=t; if (datainfo) t=t->left; else t=t->right; } nodeWithData=t; // Hold onto the data Node for later deletion // Case 1: Leaf? if (!(nodeWithData->left) && !(nodeWithData->right)) { // No Subtrees, node is leaf...Wipe it // Is it the root? if (nodeWithData==root) root=NULL; else if (trailT->right==nodeWithData) // Parent's right child trailT->right=NULL; else trailT->left=NULL; nodeToDelete=nodeWithData; // free this at the end } else if (!(nodeWithData->left)) { // If 1st condition false and this one's true, there's a right subtree if (!trailT) { // Node to delete is root and there is no left subtree nodeToDelete=root; root=root->right; } else { // Point parent's pointer to this node to this node's right child if (trailT->right==nodeWithData) trailT->right=nodeWithData->right; else trailT->left=nodeWithData->right; nodeToDelete=nodeWithData; } } else if (!(nodeWithData->right)) { // If 1st 2 conditions false and this one's true, there's a left subtree if (!trailT) { // Node to delete is root and there is no left subtree nodeToDelete=root; root=root->left; } else {// Otherwise, move up the right subtree if (trailT->right==nodeWithData) trailT->right=nodeWithData->left; else trailT->left=nodeWithData->left; nodeToDelete=nodeWithData; } } else { // If you make it here, node has two children // Go to rightmost node in left subtree; we know there's a right child... for (trailT=nodeWithData,t=nodeWithData->left; t->right!=NULL;trailT=t,t=t->right); // Want to copy data from node with 0 or 1 child to node with data to delete // Place node data in NodeWithData nodeWithData->info=t->info; // Set the parent of source node to point at source node's left child // (We know it hasn't a right child. Also ok if no left child.) if (trailT==nodeWithData) // Need to point parent correctly. // See if after the we went left there was no right child // If there was no right child, this is rightmost node in left subtree trailT->left=t->left; else // we did go right; after going left, there was a right child // rightmost node has no r. child, so point its parent at its l. child trailT->right=t->left; nodeToDelete=t; } delete nodeToDelete; } // Need Helper to Recursively Print the Tree template void BinaryTree::printInorder(TreeNode *t) const //void printTheTree(TreeNode *T) {if (t) { printInorder(t->left); cout << t->info << endl; printInorder(t->right); } } // Display Tree using InOrder Traversal template void BinaryTree::inorder() const {printInorder(root);} // Need Helper to Recursively Print the Tree template void BinaryTree::printPreorder(TreeNode *t) const //void printTheTree(TreeNode *t) {if (t) { cout << t->info << endl; printPreorder(t->left); printPreorder(t->right); } } // Display Tree using InOrder Traversal template void BinaryTree::preorder() const {printInorder(root);} // Need Helper to Recursively Print the Tree template void BinaryTree::printPostorder(TreeNode *t) const //void printTheTree(TreeNode *t) {if (t) { printPostorder(t->left); printPostorder(t->right); cout << t->info << endl; } } // Display Tree using InOrder Traversal template void BinaryTree::postorder() const {printInorder(root);} template void BinaryTree::treePrint() const {treePrintHelper(root);} template void BinaryTree:: treePrintHelper(TreeNode *root) const {queue *> Q; // A dummy node to mark end of level TreeNode *dummy=new TreeNode(-1); if (root) { cout << root->info << " " << endl; Q.push(root->left); Q.push(root->right); Q.push(dummy); } TreeNode *t=root; while (!Q.empty()) { t=Q.front(); Q.pop(); if (t==dummy) { if (!Q.empty()) Q.push(dummy); cout << endl; } else if (t) { cout << t->info << " "; Q.push(t->left); Q.push(t->right); } } } template class BinaryTree;