// Oldham, Jeffrey D. // 2000Apr09 // CS1321 // Binary Search Trees // These binary search tree routines are defined recursively since we // are using recursively defined trees. #include #include // has EXIT_SUCCESS #include #include "tree.h" // Return a tree including the given item. // If the item is already in the tree, the tree is unchanged. // We assume < is defined for ItemType. 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; } } // Query whether the given item is in the tree. // We assume < is defined for ItemType. 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; } } // Print the tree's contents. 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(); } } // Delete the specified item if present in the tree. If the item is // not present, the tree remains unchanged. A nontraditional design // decision: If both subtrees of a root are present, we choose which // subtree to modify using a random coin toss. // helper functions // input <- nonempty tree // output-> tree without its maximum element // maximum element template Tree removeMax(const Tree & t, ItemType &max) { assert(t); // not 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)); } // input <- nonempty tree // output-> tree without its minimum element // minimum element template Tree removeMin(const Tree & t, ItemType &min) { assert(t); // not 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()); } 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(). Need to find a nonempty subtree. if (t.left().empty()) return t.right(); else if (t.right().empty()) return t.left(); else { // Both subtrees not empty so flip 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); } } } } }