#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 #include // has rand() #include #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 Tree insert(const ItemType & i, const Tree & t) { if (t.empty()) return Tree(i, Tree(), Tree()); else { // nonempty tree if (i < t.item()) return Tree(t.item(), insert(i, t.left()), t.right()); else if (t.item() < i) return Tree(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 bool query(const ItemType & i, const Tree & 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 ostream& operator<<(ostream & out, const Tree & 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 Tree removeMax(const Tree & 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(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 Tree removeMin(const Tree & 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(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 Tree remove(const ItemType & i, const Tree & t) { if (t.empty()) return t; else { // nonempty tree if (i < t.item()) return Tree(t.item(), remove(i, t.left()), t.right()); else if (t.item() < i) return Tree(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(RAND_MAX) * 2 >= 1) { ItemType itm; Tree tr = removeMax(t.left(), itm); return Tree(itm, tr, t.right()); } else { ItemType itm; Tree tr = removeMin(t.right(), itm); return Tree(itm, t.left(), tr); } } } } } #endif // BST_H_