#ifndef BST_H_ #define BST_H_ // Oldham, Jeffrey D. // 2000Apr09 // CS1321 // Modified by: // Massingill, Berna L. // 2001Apr // Functions for Binary Search Trees // These binary search tree routines are defined recursively since we // are using recursively defined trees. They are template functions // since the Tree class is a template class. // We assume that "<" is defined for ItemType. #include <iostream> #include <stdlib.h> // has rand() #include <assert.h> #include "tree.h" // Function to insert an item. // Pre: t is a BST. // Post: returns a BST containing i and all elements of t. // (If t contains i already, the returned tree is // just t; otherwise it's t with i inserted.) template <class ItemType> Tree<ItemType> insert(const ItemType & i, const Tree<ItemType> & t) { if (t.empty()) return Tree<ItemType>(i, Tree<ItemType>(), Tree<ItemType>()); else { // nonempty tree if (i < t.item()) return Tree<ItemType>(t.item(), insert(i, t.left()), t.right()); else if (t.item() < i) return Tree<ItemType>(t.item(), t.left(), insert(i, t.right())); else // i == t.item() so already in the tree return t; } } // Function to search for an item. // Pre: t is a BST. // Post: returns true if i is in t, false otherwise. template <class ItemType> bool query(const ItemType & i, const Tree<ItemType> & t) { if (t.empty()) return false; else { // nonempty tree if (i < t.item()) return query(i, t.left()); else if (t.item() < i) return query(i, t.right()); else // i == t.item() return true; } } // << operator: print the tree's contents. // Post: all elements of t have been printed to "out", // in inorder-traversal order, one per line. template <class ItemType> ostream& operator<<(ostream & out, const Tree<ItemType> & t) { if (t.empty()) return out; else { // nonempty tree return out << t.left() << t.item() << endl << t.right(); } } // Functions for removing items: // Helper function to remove greatest element of BST. // Pre: t is a BST; t is not empty. // Post: "max" is the greatest element in t. // returns a BST containing all elements of t // except "max". template <class ItemType> Tree<ItemType> removeMax(const Tree<ItemType> & t, ItemType &max) { assert(!t.empty()); if (t.right().empty()) { // no right subtree max = t.item(); return t.left(); } else // nonempty right subtree return Tree<ItemType>(t.item(), t.left(), removeMax(t.right(), max)); } // Helper function to remove least element of BST. // Pre: t is a BST; t is not empty. // Post: "min" is the smallest element in t. // returns a BST containing all elements of t // except "min". template <class ItemType> Tree<ItemType> removeMin(const Tree<ItemType> & t, ItemType &min) { assert(!t.empty()); if (t.left().empty()) { // no left subtree min = t.item(); return t.right(); } else // nonempty left subtree return Tree<ItemType>(t.item(), removeMin(t.left(), min), t.right()); } // Function to remove an item. // Pre: t is a BST. // Post: returns a BST containing all elements of t except i. // (If t does not contain i, the returned tree is // just t; otherwise it's t with i removed.) template <class ItemType> Tree<ItemType> remove(const ItemType & i, const Tree<ItemType> & t) { if (t.empty()) return t; else { // nonempty tree if (i < t.item()) return Tree<ItemType>(t.item(), remove(i, t.left()), t.right()); else if (t.item() < i) return Tree<ItemType>(t.item(), t.left(), remove(i, t.right())); else { // i == t.item() if (t.left().empty()) return t.right(); else if (t.right().empty()) return t.left(); else { // neither subtree empty; "flip a // coin" to decide which to change. if (rand() / static_cast<double>(RAND_MAX) * 2 >= 1) { ItemType itm; Tree<ItemType> tr = removeMax(t.left(), itm); return Tree<ItemType>(itm, tr, t.right()); } else { ItemType itm; Tree<ItemType> tr = removeMin(t.right(), itm); return Tree<ItemType>(itm, t.left(), tr); } } } } } #endif // BST_H_