#include #include #include "book.h" #define visit(X) // Binary tree node abstract class template class BinNode { public: // Return the node's element virtual Elem& val() = 0; // Set the node's element virtual void setVal(const Elem&) = 0; // Return the node's left child virtual BinNode* left() const = 0; // Set the node's left child virtual void setLeft(BinNode*) = 0; // Return the node's right child virtual BinNode* right() const = 0; // Set the node's right child virtual void setRight(BinNode*) = 0; // Return true iff the node is a leaf virtual bool isLeaf() = 0; }; // Binary tree node class template class BinNodePtr : public BinNode { public: Elem it; // The node's value BinNodePtr* lc; // Pointer to left child BinNodePtr* rc; // Pointer to right child public: // Two constructors -- with and without initial values BinNodePtr() { lc = rc = NULL; } BinNodePtr(Elem e, BinNodePtr* l =NULL, BinNodePtr* r =NULL) { it = e; lc = l; rc = r; } ~BinNodePtr() {} // Destructor Elem& val() { return it; } void setVal(const Elem& e) { it = e; } BinNode* left() const { return lc; } void setLeft(BinNode* b) { lc = (BinNodePtr*)b; } BinNode* right() const { return rc; } void setRight(BinNode* b) { rc = (BinNodePtr*)b; } bool isLeaf() { return (lc == NULL) && (rc == NULL); } }; int count1=0; int count2=0; int countp1=0; int countp2=0; int countp3=0; // Binary tree template class bintree { private: BinNode* root; // Root of the BST public: bintree() { root = NULL; } // Constructor BinNode* getroot() { return root; } void setroot(BinNode* newroot) { root = newroot; } }; template void preorder1(BinNode* subroot) { if (subroot->left() != NULL) preorder1(subroot->left()); if (subroot->right() != NULL) preorder1(subroot->right()); } template void preorder1a(BinNodePtr* subroot) { if (subroot->lc != NULL) preorder1a(subroot->lc); if (subroot->rc != NULL) preorder1a(subroot->rc); } template void preorder1b(BinNodePtr* subroot) { BinNodePtr* myl = subroot->lc; BinNodePtr* myr = subroot->rc; if (myl != NULL) preorder1b(myl); if (myr != NULL) preorder1b(myr); } template void preorder2(BinNode* subroot) { if (subroot == NULL) return; // Empty subtree, do nothing if (subroot->left() != NULL) preorder2(subroot->left()); if (subroot->right() != NULL) preorder2(subroot->right()); } template void preorder3(BinNode* subroot) { if (subroot == NULL) return; // Empty subtree, do nothing preorder3(subroot->left()); preorder3(subroot->right()); } template void preorder3a(BinNodePtr* subroot) { if (subroot == NULL) return; // Empty subtree, do nothing preorder3a(subroot->lc); preorder3a(subroot->rc); } template BinNode* insert(BinNode* subroot, Elem val) { if (subroot == NULL) return new BinNodePtr(val); else if (Random(2) == 0) { count1++; subroot->setLeft(insert(subroot->left(), val)); return subroot; } else { count2++; subroot->setRight(insert(subroot->right(), val)); return subroot; } } template void buildRandomTree(int numnodes, bintree* tree) { for(int i=0; isetroot(insert(tree->getroot(), i)); } int main(int argc, char** argv) { bintree* tree = new bintree(); Assert(argc == 3, "Usage: travtest "); int numnodes = atoi(argv[1]); int numruns = atoi(argv[2]); int i; Randomize(); cout << "Build a tree with " << numnodes << " nodes\n"; buildRandomTree(numnodes, tree); cout << "count1 is " << count1 << "; count2 is " << count2 << endl; Settime(); for (i=0; igetroot()); cout << "Time for check-ahead (preorder1): " << Gettime() << " sec\n"; Settime(); for (i=0; i*)tree->getroot()); cout << "Time for stripped check-ahead (preorder1a): " << Gettime() << " sec\n"; Settime(); for (i=0; i*)tree->getroot()); cout << "Time for prestored check-ahead (preorder1b): " << Gettime() << " sec\n"; Settime(); for (i=0; igetroot()); cout << "Time for check-ahead with extra check (preorder2): " << Gettime() << " sec\n"; Settime(); for (i=0; i< numruns; i++) preorder3(tree->getroot()); cout << "Time for pre-check with extra recursive calls (preorder3): " << Gettime() << " sec\n"; Settime(); for (i=0; i< numruns; i++) preorder3a((BinNodePtr*)tree->getroot()); cout << "Time for stripped pre-check with extra recursive calls (preorder3a): " << Gettime() << " sec\n"; cout << "countp1: "<< countp1 << ", countp2: " << countp2 << ", countp3: " << countp3 << endl; return 0; }