// File: Tree_ADT.cpp // Binary Tree ADT implementation #include #include #include #include "Tree_ADT.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) {TreeNode *t=root,*parent; if (!t) { // Empty Tree root=new TreeNode(data); return(1); } // Search for spot to put data while(1) { if (!t) { // Nothing Here...Do the Insertion; won't be true 1st time if (datainfo) parent->left=new TreeNode(data); else parent->right=new TreeNode(data); return(1); } if (t->info==data) return(0); // data already in Tree parent=t; // Set the trail pointer to the ancestor of where we're going if (datainfo) t=t->left; else t=t->right; } } // Search for Element in Tree // Assumes == is defined for treeEltType // Returns Ptr to Elt if Found, NULL otherwise template treeEltType *BinaryTree::treeSearch(const treeEltType &key) {TreeNode *t; for (t=root;t && t->info!=key;) if (keyinfo) t=t->left; else t=t->right; if (t) return(&(t->info)); return(NULL); } // 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 // Pre: Element is in the Tree template void BinaryTree::deleteFromTree(const treeEltType &data) {TreeNode *nodeWithData,*nodeToDelete,*t,*trailT=NULL; for (t=root;t->info!=data;) { trailT=t; if (datainfo) t=t->left; else t=t->right; } nodeWithData=t; // Hold onto the data Node if (!(nodeWithData->left) && !(nodeWithData->right)) { // No Subtree, node is leaf...Wipe it // Is it the root? if (nodeWithData==root) root=NULL; else if (trailT->right==nodeWithData) trailT->right=NULL; else trailT->left=NULL; nodeToDelete=nodeWithData; // free this at the end } else if (!(nodeWithData->left)) { // No left Subtree of Node to Delete if (!trailT) { // Node to delete is root and there is no left subtree nodeToDelete=root; root=root->right; } else {// Otherwise, move up the right subtree if (trailT->right==nodeWithData) trailT->right=nodeWithData->right; else trailT->left=nodeWithData->right; nodeToDelete=nodeWithData; } } else if (!(nodeWithData->right)) { // No right Subtree of Node to Delete 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 { // 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 rightmost node to point at rightmost's left child // (We know it hasn't a right child. Also takes care if no left child. if (trailT==nodeWithData) // we just went left; // there was no right child, so this is rightmost node in left subtree trailT->left=t->left; else // we did go right; // 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;