/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Champlain College SDEV-340-81 * * C++ Week 14: Assignment (second semester) - Starting out with C++ Early Objects (9 Edition) (2020/08/15) * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Binary Search Tree - Chapter 19 (Page 1123) * Programming Challenge (1. Simple Binary Search Tree Class) * Implementing a simple binary search tree capable of storing numbers. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Written by Llewellyn van der Merwe , Aug 2020 * Copyright (C) 2020. All Rights Reserved * License GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include using namespace std; // Binary Tree Class // Adapted from Chapter 19 // IntBinaryTree class on page 1130 class Btree { private: struct BtreeNode { double value; BtreeNode* left; BtreeNode* right; BtreeNode(double value_, BtreeNode *left_ = nullptr, BtreeNode *right_ = nullptr) { value = value_; left = left_; right = right_; } }; BtreeNode* root; // Pointer to the root of the tree bool search(double num, BtreeNode *tree) const { // If the tree is empty if (!tree) { return false; } // found the value if (tree->value == num) return true; else if (num < tree->value) // recursive search search(num, tree->left); else // recursive search search(num, tree->right); } void destroySubtree(BtreeNode *tree) { if (!tree) return; destroySubtree(tree->left); destroySubtree(tree->right); // Delete the node at the root delete tree; } void remove(BtreeNode *&tree, double num) { if (tree == nullptr) return ; if (num < tree->value ) remove(tree->left, num); else if (num > tree->value) remove(tree->right, num); else // We have found the node to delete . makeDeletion (tree); } void makeDeletion(BtreeNode *&tree) { // Used to hold node that will be deleted BtreeNode *nodeToDelete = tree; // Used to locate the point where the // left subtree is attached BtreeNode *attachPoint; if (tree->right == nullptr) { // Replace tree with its left subtree tree = tree->left ; } else if (tree->left == nullptr) { // Replace tree with its right subtree tree = tree->right; } else { // The node has two children // Move to right subtree attachPoint = tree->right; // Locate the smallest node in the right subtree // by moving as far to the left as possible while (attachPoint->left != nullptr) attachPoint = attachPoint->left; // Attach the left subtree of the original tree // as the left subtree of the smallest node // in the right subtree attachPoint->left = tree->left; // Replace the original tree with its right subtree tree = tree->right; } // Delete root of original tree delete nodeToDelete; } // get the values in order, and add to vector void inorder(vector &v, BtreeNode *tree) const { if (tree) { inorder(v, tree->left); v.push_back(tree->value); inorder(v, tree->right); } } void displayInOrder(BtreeNode *tree) const { if (tree) { displayInOrder(tree->left); cout << tree->value << " "; displayInOrder(tree->right); } } void displayPreOrder(BtreeNode *tree) const { if (tree) { cout << tree->value << " "; displayPreOrder(tree->left); displayPreOrder(tree->right); } } void displayPostOrder(BtreeNode *tree) const { if (tree) { displayPostOrder(tree->left); displayPostOrder(tree->right); cout << tree->value << " "; } } public: // These member functions are the public interface. // Constructor Btree () { root = nullptr; } // Destructor ~Btree () { destroySubtree(root); } // insert function void insert(double num) { BtreeNode *tree = root; // if the tree is empty if (tree == nullptr) { root = new BtreeNode(num); return; } // tree not empty we add leaves while (true) { if (tree->value == num) { return; } else if (num < tree->value) { if (tree->left == nullptr){ tree->left = new BtreeNode(num); return; } else { tree = tree->left; } } else { if (tree->right == nullptr){ tree->right = new BtreeNode(num); return; } else { tree = tree->right; } } } } // search function bool search(double num) const { search(num, root); } // remove a node void remove(double num) { remove(root, num); } // get the values in order, and add to vector void inorder(vector &v) const { inorder(v, root); } // show in order void showInOrder(void) const { displayInOrder(root); } // show in pre order void showPreOrder() const { displayPreOrder(root); } // show in post order void showPostOrder() const { displayPostOrder(root); } }; int main() { Btree tree; cout << "Inserting the numbers 21.42, 5.52, 8.43, 3.22, 12.51, 9.13, 123.23" << endl; tree.insert(21.42); tree.insert(5.52); tree.insert(8.43); tree.insert(3.22); tree.insert(12.51); tree.insert(9.13); tree.insert(123.23); cout << "Here are the values inserted into the tree" << endl; cout << " (Pre Order)" << endl; tree.showPreOrder(); cout << "\n (Post Order)" << endl; tree.showPostOrder(); cout << "\n (In Order)" << endl; tree.showInOrder(); cout << "\n\nDeleting 8.43..." << endl; cout << "Deleting 12.51..." << endl; tree.remove (8.43); tree.remove (12.51); cout << "\nLets check if 8.43 is still in the tree:" << endl; if(tree.search(8.43)){ cout << " 8.43 found" << endl; } else { cout << " 8.43 not found" << endl; } cout << "Lets check if 9.13 is still in the tree:" << endl; if(tree.search(9.13)){ cout << " 9.13 found" << endl; } else { cout << " 9.13 not found" << endl; } cout << "\nNow, here are the remainder of the values:" << endl; cout << " (inorder vector method used)" << endl; // initialize the vector vector v; // get the order values tree.inorder(v); // print out the values for (auto i = v.begin(); i != v.end(); ++i) cout << *i << ' '; cout << endl; return 0; }