//
Purpose. Iterator design pattern lab
//
//
Problem. The BST class can traverse
itself, but, the client of the BST
// cannot stop the traversal at will
and interject application-specific
// functionality. An Iterator class is a "partner"
to a "container-like"
// class that provides the level of access
and control that a client might
// need, while still maintaining the
encapsulation of the original class.
// John Lakos has asserted that the
interface of a "container-like" class
// is not "necessary
and sufficient" until an Iterator capability is provided.
//
//
Assignment.
// o Declare a class Iterator
// o The public interface
of class Iterator should consist of -
// Iterator( BST* );
// void first();
//
void next();
// int
isDone();
// Node&
currentItem();
// o Make class Iterator a friend of class BST
// o
Add the following method to class BST
// Iterator* createIterator();
// o Add the following to
the end of main() -
// create
an Iterator object
// in a for
loop, traverse the BST by using Iterator's first(), next(),
// isDone(), and currentItem()
methods
// in a second for
loop, traverse the BST again
//
deallocate the Iterator object
// o The BST::createIterator()
implementation needs to create and return an
// "appropriately initialized" instance of class
Iterator
// o The school solution private data members of class Iterator
are:
// BST* bst;
// Node** list;
// int
nextNode;
// o A strategy for the Iterator::first() implementation
is -
// create a dynamic array
of type Node* whose size is equal to the number
// of nodes in the BST
// traverse the BST, copying each Node*
into the dynamic array (the array
// will now "mirror" the BST)
// initialize a "next array
element" data member to 0
// o Traversing the BST to initialize the
dynamic array could be implemented
//
by defining a recursive function that looks a lot like the current
// BST::traverse(Node*) method. The school solution implementation
defines
// the following private
utility method -
// void
buildList( Node* current ) {
//
if (current->left != 0) buildList( current->left );
// list[nextNode++] = current;
// if (current->right != 0)
buildList( current->right );
//
}
// o Iterator::next() simply increments the "next array
element" data member
// o Iterator::currentItem() uses the "next
array element" data member to
//
index into the dynamic array and then returns the dereferenced
pointer
// o Iterator::isDone() needs an implementation
// o The
dynamic array created in Iterator::first() needs to be deallocated if
// a second call to Iterator::first() is
made
#include <iostream.h>
#include
<stdlib.h>
#include <time.h>
struct Node {
int value;
Node* left; Node* right;
Node() { left = right = 0; }
friend ostream& operator<< (
ostream& os, Node& n ) { return os << n.value; }
};
class BST {
private:
Node* root;
int
size;
public:
BST()
{
root = 0;
}
void add( int in ) {
if (root == 0) {
root = new Node;
root->value = in;
size = 1;
return;
}
add( in, root );
}
void traverse() { traverse( root ); }
private:
void add( int in, Node* current ) {
if (in < current->value)
if (current->left == 0) {
current->left = new
Node();
current->left->value = in;
size++;
}
else add( in,
current->left );
else
if
(current->right == 0) {
current->right = new Node();
current->right->value = in;
size++;
}
else add( in, current->right );
}
void traverse( Node* current ) {
if (current->left != 0) traverse( current->left
);
cout <<
current->value << "
";
if
(current->right != 0) traverse( current->right );
}
};
void main( void )
{
BST bst;
time_t t;
srand((unsigned) time(&t));
cout << "original: ";
for (int i=0, val; i < 15; i++) {
val = rand() % 49 + 1;
cout << val << " ";
bst.add( val );
}
cout <<
"\ntraverse: ";
bst.traverse();
cout << endl;
}
//
original: 11 43 7 2 22 3
25 40 41 36 32
11 24 11 37
//
traverse: 2 3 7 11
11 11 22 24 25
32 36 37 40 41
43
// Iterator: 2 3
7 11 11 11 22
24 25 32 36 37
40 41 43
// Iterator:
2 3 7 11 11
11 22 24 25 32
36 37 40 41 43