// // simplified implementation of set data type // // Described in Chapter 12 of // Data Structures in C++ using the STL // Published by Addison-Wesley, 1997 // Written by Tim Budd, budd@cs.orst.edu // Oregon State University // template class node { public: node (T & v, node * par, node * left, node * right) : value(v), parent(par), leftChild(left), rightChild(right) { } // operations node * copy ( node *); void release (); int count (T & testElement); void insert (node *); int size (); node * merge (node *, node *); inorderTreeTraversal lower_bound(T &, inorderTreeTraversal &); inorderTreeTraversal upper_bound(T &, inorderTreeTraversal &); // data fields T value; node * parent; node * leftChild; node * rightChild; }; template class inorderTreeTraversal { public: typedef inorderTreeTraversal iterator; // constructor inorderTreeTraversal (node * s); inorderTreeTraversal (iterator & itr) : current (itr.current) { } // iterator protocol inorderTreeTraversal & operator ++(); inorderTreeTraversal operator ++(int); T & operator * () { return current->value; } void operator = (iterator & itr) { current = itr.current; } bool operator == (iterator & rhs) { return current == rhs.current; } protected: node * current; }; # if 0 template inorderTreeTraveral inorderTreeTraversal::operator ++ (int) { // clone ourselves using the copy constructor inorderTreeTraversal clone (*this); operator ++ (); // increment ourselves return clone; // return copy } # endif template inorderTreeTraversal::inorderTreeTraversal (node * root) // initialize inorder traversal { current = root; // perform a left slide while (current && current->leftChild) current = current->leftChild; } template class set { public: typedef inorderTreeTraversal iterator; // constructor set () { root = 0; } // tree traversing operations void insert (T &); void erase (T & testElement) { root = remove (root, testElement); } int count (T & testElement); iterator lower_bound (T & testElement); iterator upper_bound (T & testElement); // other operations bool empty () { return root == 0; } int size (); void swap (set & right) { ::swap (root, right.root); } protected: // root of binary search tree node * root; // internal method used in removal node * remove (node *, T &); }; template int set::size() // count the number of elements in set { if (root == 0) return 0; else return root->size(); } template int node::size() // count number of elements in subtree rooted at node { int count = 1; if (leftChild != 0) count += leftChild.size(); if (rightChild != 0) count += rightChild.size(); return count; } template inorderTreeTraversal set::lower_bound (T & element) // find first occurrence of element in collection { if (root == 0) return end(); else return root->lower_bound(element, end()); } template inorderTreeTraversal node::lower_bound (T & element, inorderTreeTraversal & end) { if (value < element) if (rightChild != 0) return rightChild->lower_bound (element, end); else return end; // not found at all // check left child if (leftChild != 0) { // see if it is found along left child set::iterator result = leftChild->lower_bound (element, end); if (result != end) // found it, must be first return result; } // not found in left child, either we are it or not found at all if (element < value) return end; // not found at all else return setIterator(this); // make iterator that points to us } template inorderTreeTraversal node::upper_bound (T & element, inorderTreeTraversal & end) { if (value < element) if (rightChild != 0) return rightChild->upper_bound (element, end); else return end; // not found at all if (leftChild != 0) { iterator result = leftChild->upper_bound (element, end); if (result != end) return result; } if (element < value) return setIterator (this); return end; } template int set::count (T & element) // count number of occurrences of element { iterator first = lower_bound(element); iterator last = upper_bound(element); int counter = 0; // count number of elements between lower and upper while (first != last) { counter++; first++; } return counter; } template void set::insert (T & newElement) // insert a new element into a set { // do not insert if already in set if (count(newElement) > 0) return; // create a new node node * newNode = new node (newElement, 0, 0, 0); // see if collection is empty if (root == 0) root = newNode; else root->insert (newNode); } template void node::insert (node * newNode) // insert a new element into a binary search tree { if (newElement < value) if (leftChild != 0) leftChild->insert (newNode); else { newNode->parent = this; leftChild = newNode; } else if (rightChild != 0) rightChild->insert (newNode); else { newNode->parent = this; rightChild = newNode; } } template node * node::merge (node * left, node * right) // merge two subtrees into one { if (left == 0) return right; if (right == 0) return left; node * child = merge(left, right->leftChild); child->parent = right; right->leftChild = child; return right; } template node * set::remove (node * current, T & testElement) // remove all instances of testElement from collection { if (current != 0) { node * pa = current->parent; if (testElement < current->value) current->leftChild = remove (current->leftChild, testElement); else if (current->value < testElement) current->rightChild = remove (current->rightChild, testElement); else { // found an item to remove node * result = current->merge(current->leftChild, remove (current->rightChild, testElement)); delete current; result->parent = pa; return result; } } return current; }