You are on page 1of 51

SOURCE CODE FOR DATA STRUCTURES AND

ALGORITHM ANALYSIS IN C++

VECTOR.H

#ifndef VECTOR_H
#define VECTOR_H

#define vector Vector

class ArrayIndexOutOfBounds { };

template <class Object>


class vector
{
public:
explicit vector( int theSize = 0 ) : currentSize( theSize )
{ objects = new Object[ currentSize ]; }
vector( const vector & rhs ) : objects( NULL )
{ operator=( rhs ); }
~vector( )
#ifndef WIN32
{ delete [ ] objects; }
#else
{ if( currentSize != 0 ) delete [ ] objects; }
#endif

int size( ) const


{ return currentSize; }

Object & operator[]( int index )


{
#ifndef NO_CHECK
if( index < 0 || index >= currentSize )
throw ArrayIndexOutOfBounds( );
#endif
return objects[ index ];
}

const Object & operator[]( int index ) const


{
#ifndef NO_CHECK
if( index < 0 || index >= currentSize )
throw ArrayIndexOutOfBounds( );
#endif
return objects[ index ];
}
const vector & operator = ( const vector & rhs );
void resize( int newSize );
private:
int currentSize;
Object * objects;
};

#include "vector.cpp"
#endif

VECTOR.CPP

#ifndef VECTOR_CPP_
#define VECTOR_CPP_

#include "vector.h"

template <class Object>


const vector<Object> & vector<Object>::operator=( const vector<Object> &
rhs )
{
if( this != &rhs )
{
#ifdef WIN32
if( currentSize != 0 )
#endif
delete [ ] objects;
currentSize = rhs.size( );
objects = new Object[ currentSize ];
for( int k = 0; k < currentSize; k++ )
objects[ k ] = rhs.objects[ k ];
}
return *this;
}

template <class Object>


void vector<Object>::resize( int newSize )
{
Object *oldArray = objects;
int numToCopy = newSize < currentSize ? newSize : currentSize;

objects = new Object[ newSize ];

for( int k = 0; k < numToCopy; k++ )


objects[ k ] = oldArray[ k ];

#ifdef WIN32
if( currentSize != 0 )
#endif
delete [ ] oldArray;
currentSize = newSize;
}

#endif
Fig01_02.cpp: A simple recursive routine with a test
program

#include <iostream.h>

int f( int x )
{
/* 1*/ if( x == 0 )
/* 2*/ return 0;
else
/* 3*/ return 2 * f( x - 1 ) + x * x;
}

int main( )
{
cout << "f(5) = " << f( 5 ) << endl;
return 0;
}

LinkedList.h: Header file for linked list

#ifndef LinkedList_H
#define LinkedList_H

#include "dsexceptions.h"
#include <iostream.h> // For NULL

// List class
//
// CONSTRUCTION: with no initializer
// Access is via ListItr class
//
// ******************PUBLIC OPERATIONS*********************
// boolean isEmpty( ) --> Return true if empty; else false
// void makeEmpty( ) --> Remove all items
// ListItr zeroth( ) --> Return position to prior to first
// ListItr first( ) --> Return first position
// void insert( x, p ) --> Insert x after current iterator
position p
// void remove( x ) --> Remove x
// ListItr find( x ) --> Return position that views x
// ListItr findPrevious( x )
// --> Return position prior to x
// ******************ERRORS********************************
// No special errors

template <class Object>


class List; // Incomplete declaration.

template <class Object>


class ListItr; // Incomplete declaration.

template <class Object>


class ListNode
{
ListNode( const Object & theElement = Object( ), ListNode *
n = NULL )
: element( theElement ), next( n ) { }

Object element;
ListNode *next;

friend class List<Object>;


friend class ListItr<Object>;
};

template <class Object>


class List
{
public:
List( );
List( const List & rhs );
~List( );

bool isEmpty( ) const;


void makeEmpty( );
ListItr<Object> zeroth( ) const;
ListItr<Object> first( ) const;
void insert( const Object & x, const ListItr<Object> & p );
ListItr<Object> find( const Object & x ) const;
ListItr<Object> findPrevious( const Object & x ) const;
void remove( const Object & x );

const List & operator=( const List & rhs );

private:
ListNode<Object> *header;
};

// ListItr class; maintains "current position"


//
// CONSTRUCTION: Package friendly only, with a ListNode
//
// ******************PUBLIC OPERATIONS*********************
// bool isPastEnd( ) --> True if past end position in list
// void advance( ) --> Advance (if not already null)
// Object retrieve --> Return item in current position

template <class Object>


class ListItr
{
public:
ListItr( ) : current( NULL ) { }
bool isPastEnd( ) const
{ return current == NULL; }
void advance( )
{ if( !isPastEnd( ) ) current = current->next; }
const Object & retrieve( ) const
{ if( isPastEnd( ) ) throw BadIterator( );
return current->element; }

private:
ListNode<Object> *current; // Current position

ListItr( ListNode<Object> *theNode )


: current( theNode ) { }

friend class List<Object>; // Grant access to constructor


};

#include "LinkedList.cpp"
#endif
LinkedList.cpp: Implementation for linked list

#include "LinkedList.h"

/**
* Construct the list
*/
template <class Object>
List<Object>::List( )
{
header = new ListNode<Object>;
}

/**
* Copy constructor
*/
template <class Object>
List<Object>::List( const List<Object> & rhs )
{
header = new ListNode<Object>;
*this = rhs;
}

/**
* Destructor
*/
template <class Object>
List<Object>::~List( )
{
makeEmpty( );
delete header;
}

/**
* Test if the list is logically empty.
* return true if empty, false otherwise.
*/
template <class Object>
bool List<Object>::isEmpty( ) const
{
return header->next == NULL;
}

/**
* Make the list logically empty.
*/
template <class Object>
void List<Object>::makeEmpty( )
{
while( !isEmpty( ) )
remove( first( ).retrieve( ) );
}

/**
* Return an iterator representing the header node.
*/
template <class Object>
ListItr<Object> List<Object>::zeroth( ) const
{
return ListItr<Object>( header );
}

/**
* Return an iterator representing the first node in the list.
* This operation is valid for empty lists.
*/
template <class Object>
ListItr<Object> List<Object>::first( ) const
{
return ListItr<Object>( header->next );
}

/**
* Insert item x after p.
*/
template <class Object>
void List<Object>::insert( const Object & x, const
ListItr<Object> & p )
{
if( p.current != NULL )
p.current->next = new ListNode<Object>( x, p.current-
>next );
}

/**
* Return iterator corresponding to the first node containing an
item x.
* Iterator isPastEnd if item is not found.
*/
template <class Object>
ListItr<Object> List<Object>::find( const Object & x ) const
{
/* 1*/ ListNode<Object> *itr = header->next;

/* 2*/ while( itr != NULL && itr->element != x )


/* 3*/ itr = itr->next;

/* 4*/ return ListItr<Object>( itr );


}

/**
* Return iterator prior to the first node containing an item x.
*/
template <class Object>
ListItr<Object> List<Object>::findPrevious( const Object & x )
const
{
/* 1*/ ListNode<Object> *itr = header;

/* 2*/ while( itr->next != NULL && itr->next->element != x )


/* 3*/ itr = itr->next;

/* 4*/ return ListItr<Object>( itr );


}

/**
* Remove the first occurrence of an item x.
*/
template <class Object>
void List<Object>::remove( const Object & x )
{
ListItr<Object> p = findPrevious( x );

if( p.current->next != NULL )


{
ListNode<Object> *oldNode = p.current->next;
p.current->next = p.current->next->next; // Bypass
deleted node
delete oldNode;
}
}

/**
* Deep copy of linked lists.
*/
template <class Object>
const List<Object> & List<Object>::operator=( const List<Object>
& rhs )
{
ListItr<Object> ritr = rhs.first( );
ListItr<Object> itr = zeroth( );

if( this != &rhs )


{
makeEmpty( );
for( ; !ritr.isPastEnd( ); ritr.advance( ), itr.advance(
) )
insert( ritr.retrieve( ), itr );
}
return *this;
}

TestLinkedList.cpp: Test program for linked list package

#include <iostream.h>
#include "LinkedList.h"

// Simple print method


template <class Object>
void printList( const List<Object> & theList )
{
if( theList.isEmpty( ) )
cout << "Empty list" << endl;
else
{
ListItr<Object> itr = theList.first( );
for( ; !itr.isPastEnd( ); itr.advance( ) )
cout << itr.retrieve( ) << " ";
}

cout << endl;


}

int main( )
{
List<int> theList;
ListItr<int> theItr = theList.zeroth( );
int i;

printList( theList );

for( i = 0; i < 10; i++ )


{
theList.insert( i, theItr );
printList( theList );
theItr.advance( );
}

for( i = 0; i < 10; i += 2 )


theList.remove( i );
for( i = 0; i < 10; i++ )
if( ( i % 2 == 0 ) != ( theList.find( i ).isPastEnd( ) )
)
cout << "Find fails!" << endl;

cout << "Finished deletions" << endl;


printList( theList );

List<int> list2;
list2 = theList;
printList( list2 );

return 0;
}

Polynomial.cpp: Polynomials

/*
* This code doesn't really do much, and abstraction is not built
in.
* Thus, I haven't bothered testing it exhaustively.
*/
#include <iostream.h>
#include "vector.h"

class Polynomial
{
enum { MAX_DEGREE = 100 };
friend int main( ); // So I can do a quick test.

public:
Polynomial( );
void zeroPolynomial( );
Polynomial operator+( const Polynomial & rhs ) const;
Polynomial operator*( const Polynomial & rhs ) const;
void print( ostream & out ) const;

private:
vector<int> coeffArray;
int highPower;
};

int max( int a, int b )


{
return a > b ? a : b;
}

Polynomial::Polynomial( ) : coeffArray( MAX_DEGREE + 1 )


{
zeroPolynomial( );
}

void Polynomial::zeroPolynomial( )
{
for( int i = 0; i <= MAX_DEGREE; i++ )
coeffArray[ i ] = 0;
highPower = 0;
}

Polynomial Polynomial::operator+( const Polynomial & rhs ) const


{
Polynomial sum;

sum.highPower = max( highPower, rhs.highPower );


for( int i = sum.highPower; i >= 0; i-- )
sum.coeffArray[ i ] = coeffArray[ i ] +
rhs.coeffArray[ i ];
return sum;
}

Polynomial Polynomial::operator*( const Polynomial & rhs ) const


{
Polynomial product;

product.highPower = highPower + rhs.highPower;


if( product.highPower > MAX_DEGREE )
cerr << "operator* exceeded MAX_DEGREE" << endl;
for( int i = 0; i <= highPower; i++ )
for( int j = 0; j <= rhs.highPower; j++ )
product.coeffArray[ i + j ] +=
coeffArray[ i ] * rhs.coeffArray[ j ];
return product;
}

void Polynomial::print( ostream & out ) const


{
for( int i = highPower; i > 0; i-- )
out << coeffArray[ i ] << "x^" << i << " + ";
out << coeffArray[ 0 ] << endl;
}

ostream & operator<<( ostream & out, const Polynomial & rhs )
{
rhs.print( out );
return out;
}

int main( )
{
Polynomial p;
Polynomial q;

p.highPower = 1; p.coeffArray[ 0 ] = 1; p.coeffArray[ 1 ] =


1;

q = p + p;
p = q * q;
q = p + p;

cout << q << endl;


return 0;
}
CursorList.h: Header file for cursor linked list

#ifndef CursorList_H
#define CursorList_H

#define List CursorList

#include "vector.h"
#include "dsexceptions.h"

// LinkedList class using a cursor implementation


//
// CONSTRUCTION: with no initializer
// Access is via LinkedListItr class
//
// ******************PUBLIC OPERATIONS*********************
// boolean isEmpty( ) --> Return true if empty; else false
// void makeEmpty( ) --> Remove all items
// ListItr zeroth( ) --> Return position to prior to first
// ListItr first( ) --> Return first position
// void insert( x, p ) --> Insert x after current iterator
position p
// void remove( x ) --> Remove x
// ListItr find( x ) --> Return position that views x
// ListItr findPrevious( x )
// --> Return position prior to x
// ******************ERRORS********************************
// No special errors

template <class Object>


class ListItr; // Incomplete declaration.

template <class Object>


class List
{
public:
List( );
List( const List & rhs );
~List( );

bool isEmpty( ) const;


void makeEmpty( );
ListItr<Object> zeroth( ) const;
ListItr<Object> first( ) const;
void insert( const Object & x, const ListItr<Object> & p );
ListItr<Object> find( const Object & x ) const;
ListItr<Object> findPrevious( const Object & x ) const;
void remove( const Object & x );

public:
struct CursorNode
{
CursorNode( ) : next( 0 ) { }

private:
CursorNode( const Object & theElement, int n )
: element( theElement ), next( n ) { }

Object element;
int next;

friend class List<Object>;


friend class ListItr<Object>;
};

const List & operator=( const List & rhs );

private:
int header;

static vector<CursorNode> cursorSpace;

static void initializeCursorSpace( );


static int alloc( );
static void free( int p );

friend class ListItr<Object>;


};

// ListItr class; maintains "current position"


//
// CONSTRUCTION: Package friendly only, with an int
//
// ******************PUBLIC OPERATIONS*********************
// bool isPastEnd( ) --> True if at valid position in list
// void advance( ) --> Advance (if not already null)
// Object retrieve --> Return item in current position

template <class Object>


class ListItr
{
public:
ListItr( ) : current( 0 ) { }
bool isPastEnd( ) const
{ return current == 0; }
void advance( )
{ if( !isPastEnd( ) ) current = List<Object>::cursorSpace[
current ].next; }
const Object & retrieve( ) const
{ if( isPastEnd( ) ) throw BadIterator( );
return List<Object>::cursorSpace[ current ].element; }

private:
int current; // Current position
friend class List<Object>;

ListItr( int theNode )


: current( theNode ) { }
};

#include "CursorList.cpp"
#endif
CursorList.cpp: Implementation for cursor linked list

#include "CursorList.h"

/**
* Routine to initialize the cursorSpace.
*/
template <class Object>
void List<Object>::initializeCursorSpace( )
{
static int cursorSpaceIsInitialized = false;

if( !cursorSpaceIsInitialized )
{
cursorSpace.resize( 100 );
for( int i = 0; i < cursorSpace.size( ); i++ )
cursorSpace[ i ].next = i + 1;
cursorSpace[ cursorSpace.size( ) - 1 ].next = 0;
cursorSpaceIsInitialized = true;
}
}

/**
* Allocate a CursorNode
*/
template <class Object>
int List<Object>::alloc( )
{
int p = cursorSpace[ 0 ].next;
cursorSpace[ 0 ].next = cursorSpace[ p ].next;
return p;
}

/**
* Free a CursorNode
*/
template <class Object>
void List<Object>::free( int p )
{
cursorSpace[ p ].next = cursorSpace[ 0 ].next;
cursorSpace[ 0 ].next = p;
}

/**
* Construct the list
*/
template <class Object>
List<Object>::List( )
{
initializeCursorSpace( );
header = alloc( );
cursorSpace[ header ].next = 0;
}

/**
* Copy constructor
*/
template <class Object>
List<Object>::List( const List<Object> & rhs )
{
initializeCursorSpace( );
header = alloc( );
cursorSpace[ header ].next = 0;
*this = rhs;
}

/**
* Destroy the list
*/
template <class Object>
List<Object>::~List( )
{
makeEmpty( );
free( header );
}

/**
* Test if the list is logically empty.
* return true if empty, false otherwise.
*/
template <class Object>
bool List<Object>::isEmpty( ) const
{
return cursorSpace[ header ].next == 0;
}

/**
* Make the list logically empty.
*/
template <class Object>
void List<Object>::makeEmpty( )
{
while( !isEmpty( ) )
remove( first( ).retrieve( ) );
}

/**
* Return an iterator representing the header node.
*/
template <class Object>
ListItr<Object> List<Object>::zeroth( ) const
{
return ListItr<Object>( header );
}

/**
* Return an iterator representing the first node in the list.
* This operation is valid for empty lists.
*/
template <class Object>
ListItr<Object> List<Object>::first( ) const
{
return ListItr<Object>( cursorSpace[ header ].next );
}

/**
* Insert item x after p.
*/
template <class Object>
void List<Object>::insert( const Object & x, const
ListItr<Object> & p )
{
if( p.current != 0 )
{
int pos = p.current;
int tmp = alloc( );

cursorSpace[ tmp ] = CursorNode( x,


cursorSpace[ pos ].next );
cursorSpace[ pos ].next = tmp;
}
}

/**
* Return iterator corresponding to the first node containing an
item x.
* Iterator isPastEnd if item is not found.
*/
template <class Object>
ListItr<Object> List<Object>::find( const Object & x ) const
{
/* 1*/ int itr = cursorSpace[ header ].next;

/* 2*/ while( itr != 0 && cursorSpace[ itr ].element != x )


/* 3*/ itr = cursorSpace[ itr ].next;

/* 4*/ return ListItr<Object>( itr );


}

/**
* Return iterator prior to the first node containing an item x.
*/
template <class Object>
ListItr<Object> List<Object>::findPrevious( const Object & x )
const
{
/* 1*/ int itr = header;

/* 2*/ while( cursorSpace[ itr ].next != 0 &&


cursorSpace[ cursorSpace[ itr ].next ].element != x )
/* 3*/ itr = cursorSpace[ itr ].next;

/* 4*/ return ListItr<Object>( itr );


}

/**
* Remove the first occurrence of an item x.
*/
template <class Object>
void List<Object>::remove( const Object & x )
{
ListItr<Object> p = findPrevious( x );
int pos = p.current;

if( cursorSpace[ pos ].next != 0 )


{
int tmp = cursorSpace[ pos ].next;
cursorSpace[ pos ].next = cursorSpace[ tmp ].next;
free ( tmp );
}
}

/**
* Deep copy of linked lists.
*/
template <class Object>
const List<Object> & List<Object>::operator=( const List<Object>
& rhs )
{
ListItr<Object> ritr = rhs.first( );
ListItr<Object> itr = zeroth( );

if( this != &rhs )


{
makeEmpty( );
for( ; !ritr.isPastEnd( ); ritr.advance( ), itr.advance(
) )
insert( ritr.retrieve( ), itr );
}
return *this;
}

TestCursorList.cpp: Test program for cursor implementation of linked lists

#include <iostream.h>
#include "CursorList.h"

// Simple print method


template <class Object>
void printList( const List<Object> & theList )
{
if( theList.isEmpty( ) )
cout << "Empty list" << endl;
else
{
ListItr<Object> itr = theList.first( );
for( ; !itr.isPastEnd( ); itr.advance( ) )
cout << itr.retrieve( ) << " ";
}

cout << endl;


}
vector<List<int>::CursorNode> List<int>::cursorSpace;

int main( )
{
List<int> theList;
ListItr<int> theItr = theList.zeroth( );
int i;

printList( theList );

for( i = 0; i < 10; i++ )


{
theList.insert( i, theItr );
printList( theList );
theItr.advance( );
}

for( i = 0; i < 10; i += 2 )


theList.remove( i );

for( i = 0; i < 10; i++ )


if( ( i % 2 == 0 ) != ( theList.find( i ).isPastEnd( ) )
)
cout << "Find fails!" << endl;

cout << "Finished deletions" << endl;


printList( theList );

return 0;
}

StackAr.h: Header file for stack: array version

#ifndef STACKAR_H
#define STACKAR_H

#include "vector.h"
#include "dsexceptions.h"

// Stack class -- array implementation


//
// CONSTRUCTION: with or without a capacity; default is 10
//
// ******************PUBLIC OPERATIONS*********************
// void push( x ) --> Insert x
// void pop( ) --> Remove most recently inserted item
// Object top( ) --> Return most recently inserted item
// Object topAndPop( ) --> Return and remove most recently
inserted item
// bool isEmpty( ) --> Return true if empty; else false
// bool isFull( ) --> Return true if full; else false
// void makeEmpty( ) --> Remove all items
// ******************ERRORS********************************
// Overflow and Underflow thrown as needed
template <class Object>
class Stack
{
public:
explicit Stack( int capacity = 10 );

bool isEmpty( ) const;


bool isFull( ) const;
const Object & top( ) const;

void makeEmpty( );
void pop( );
void push( const Object & x );
Object topAndPop( );

private:
vector<Object> theArray;
int topOfStack;
};

#include "StackAr.cpp"
#endif
StackAr.cpp: Implementation for stack: array version

#include "StackAr.h"

/**
* Construct the stack.
*/
template <class Object>
Stack<Object>::Stack( int capacity ) : theArray( capacity )
{
topOfStack = -1;
}

/**
* Test if the stack is logically empty.
* Return true if empty, false otherwise.
*/
template <class Object>
bool Stack<Object>::isEmpty( ) const
{
return topOfStack == -1;
}

/**
* Test if the stack is logically full.
* Return true if full, false otherwise.
*/
template <class Object>
bool Stack<Object>::isFull( ) const
{
return topOfStack == theArray.size( ) - 1;
}

/**
* Make the stack logically empty.
*/
template <class Object>
void Stack<Object>::makeEmpty( )
{
topOfStack = -1;
}

/**
* Get the most recently inserted item in the stack.
* Does not alter the stack.
* Return the most recently inserted item in the stack.
* Exception Underflow if stack is already empty.
*/
template <class Object>
const Object & Stack<Object>::top( ) const
{
if( isEmpty( ) )
throw Underflow( );
return theArray[ topOfStack ];
}

/**
* Remove the most recently inserted item from the stack.
* Exception Underflow if stack is already empty.
*/
template <class Object>
void Stack<Object>::pop( )
{
if( isEmpty( ) )
throw Underflow( );
topOfStack--;
}

/**
* Insert x into the stack, if not already full.
* Exception Overflow if stack is already full.
*/
template <class Object>
void Stack<Object>::push( const Object & x )
{
if( isFull( ) )
throw Overflow( );
theArray[ ++topOfStack ] = x;
}

/**
* Return and remove most recently inserted item from the stack.
* Return most recently inserted item.
* Exception Underflow if stack is already empty.
*/
template <class Object>
Object Stack<Object>::topAndPop( )
{
if( isEmpty( ) )
throw Underflow( );
return theArray[ topOfStack-- ];
}
TestStackAr.cpp: Test program for (array-based) stacks

#include <iostream.h>
#include "StackAr.h"

int main( )
{
Stack<int> s;

for( int i = 0; i < 10; i++ )


s.push( i );

while( !s.isEmpty( ) )
cout << s.topAndPop( ) << endl;

return 0;
}

StackLi.h: Header file for stack: list version

#ifndef STACKLI_H
#define STACKLI_H

#include "dsexceptions.h"
#include <iostream.h> // For NULL

// Stack class -- linked list implementation


//
// CONSTRUCTION: with no parameters
//
// ******************PUBLIC OPERATIONS*********************
// void push( x ) --> Insert x
// void pop( ) --> Remove most recently inserted item
// Object top( ) --> Return most recently inserted item
// Object topAndPop( ) --> Return and remove most recently
inserted item
// bool isEmpty( ) --> Return true if empty; else false
// bool isFull( ) --> Return true if full; else false
// void makeEmpty( ) --> Remove all items
// ******************ERRORS********************************
// Overflow and Underflow thrown as needed

template <class Object>


class Stack
{
public:
Stack( );
Stack( const Stack & rhs );
~Stack( );

bool isEmpty( ) const;


bool isFull( ) const;
const Object & top( ) const;
void makeEmpty( );
void pop( );
void push( const Object & x );
Object topAndPop( );

const Stack & operator=( const Stack & rhs );

private:
struct ListNode
{
Object element;
ListNode *next;

ListNode( const Object & theElement, ListNode * n = NULL


)
: element( theElement ), next( n ) { }
};

ListNode *topOfStack;
};

#include "StackLi.cpp"
#endif

StackLi.cpp: Implementation for stack: list version

#include "StackLi.h"
#include <iostream.h>

/**
* Construct the stack.
*/
template <class Object>
Stack<Object>::Stack( )
{
topOfStack = NULL;
}

/**
* Copy constructor.
*/
template <class Object>
Stack<Object>::Stack( const Stack<Object> & rhs )
{
topOfStack = NULL;
*this = rhs;
}

/**
* Destructor.
*/
template <class Object>
Stack<Object>::~Stack( )
{
makeEmpty( );
}

/**
* Test if the stack is logically full.
* Return false always, in this implementation.
*/
template <class Object>
bool Stack<Object>::isFull( ) const
{
return false;
}

/**
* Test if the stack is logically empty.
* Return true if empty, false otherwise.
*/
template <class Object>
bool Stack<Object>::isEmpty( ) const
{
return topOfStack == NULL;
}

/**
* Make the stack logically empty.
*/
template <class Object>
void Stack<Object>::makeEmpty( )
{
while( !isEmpty( ) )
pop( );
}

/**
* Get the most recently inserted item in the stack.
* Return the most recently inserted item in the stack
* or throw an exception if empty.
*/
template <class Object>
const Object & Stack<Object>::top( ) const
{
if( isEmpty( ) )
throw Underflow( );
return topOfStack->element;
}

/**
* Remove the most recently inserted item from the stack.
* Exception Underflow if the stack is empty.
*/
template <class Object>
void Stack<Object>::pop( )
{
if( isEmpty( ) )
throw Underflow( );

ListNode *oldTop = topOfStack;


topOfStack = topOfStack->next;
delete oldTop;
}

/**
* Return and remove the most recently inserted item
* from the stack.
*/
template <class Object>
Object Stack<Object>::topAndPop( )
{
Object topItem = top( );
pop( );
return topItem;
}

/**
* Insert x into the stack.
*/
template <class Object>
void Stack<Object>::push( const Object & x )
{
topOfStack = new ListNode( x, topOfStack );
}

/**
* Deep copy.
*/
template <class Object>
const Stack<Object> & Stack<Object>::
operator=( const Stack<Object> & rhs )
{
if( this != &rhs )
{
makeEmpty( );
if( rhs.isEmpty( ) )
return *this;

ListNode *rptr = rhs.topOfStack;


ListNode *ptr = new ListNode( rptr->element );
topOfStack = ptr;

for( rptr = rptr->next; rptr != NULL; rptr = rptr-


>next )
ptr = ptr->next = new ListNode( rptr->element );
}
return *this;
}
TestStackLi.cpp: Test program for (list-based) stacks

#include "StackLi.h"
#include <iostream.h>

int main( )
{
Stack<int> s, s1;
for( int i = 0; i < 10; i++ )
s.push( i );

s1 = s;

cout << "s" << endl;


while( !s.isEmpty( ) )
cout << s.topAndPop( ) << endl;

cout << endl << "s1" << endl;


while( !s1.isEmpty( ) )
cout << s1.topAndPop( ) << endl;

return 0;
}

QueueAr.h: Header file for queue: array version

#ifndef QUEUEAR_H
#define QUEUEAR_H

#include "vector.h"
#include "dsexceptions.h"

// Queue class -- array implementation


//
// CONSTRUCTION: with or without a capacity; default is 10
//
// ******************PUBLIC OPERATIONS*********************
// void enqueue( x ) --> Insert x
// void dequeue( ) --> Return and remove least recently
inserted item
// Object getFront( ) --> Return least recently inserted
item
// bool isEmpty( ) --> Return true if empty; else false
// bool isFull( ) --> Return true if full; else false
// void makeEmpty( ) --> Remove all items
// ******************ERRORS********************************
// Overflow and Underflow thrown as needed

template <class Object>


class Queue
{
public:
explicit Queue( int capacity = 10 );

bool isEmpty( ) const;


bool isFull( ) const;
const Object & getFront( ) const;

void makeEmpty( );
Object dequeue( );
void enqueue( const Object & x );

private:
vector<Object> theArray;
int currentSize;
int front;
int back;

void increment( int & x );


};

#include "QueueAr.cpp"
#endif
QueueAr.cpp: Implementation for queue: array version

#include "QueueAr.h"

/**
* Construct the queue.
*/
template <class Object>
Queue<Object>::Queue( int capacity ) : theArray( capacity )
{
makeEmpty( );
}

/**
* Test if the queue is logically empty.
* Return true if empty, false otherwise.
*/
template <class Object>
bool Queue<Object>::isEmpty( ) const
{
return currentSize == 0;
}

/**
* Test if the queue is logically full.
* Return true if full, false otherwise.
*/
template <class Object>
bool Queue<Object>::isFull( ) const
{
return currentSize == theArray.size( );
}

/**
* Make the queue logically empty.
*/
template <class Object>
void Queue<Object>::makeEmpty( )
{
currentSize = 0;
front = 0;
back = -1;
}

/**
* Get the least recently inserted item in the queue.
* Return the least recently inserted item in the queue
* or throw Underflow if empty.
*/
template <class Object>
const Object & Queue<Object>::getFront( ) const
{
if( isEmpty( ) )
throw Underflow( );
return theArray[ front ];
}

/**
* Return and remove the least recently inserted item from the
queue.
* Throw Underflow if empty.
*/
template <class Object>
Object Queue<Object>::dequeue( )
{
if( isEmpty( ) )
throw Underflow( );

currentSize--;
Object frontItem = theArray[ front ];
increment( front );
return frontItem;
}

/**
* Insert x into the queue.
* Throw Overflow if queue is full
*/
template <class Object>
void Queue<Object>::enqueue( const Object & x )
{
if( isFull( ) )
throw Overflow( );
increment( back );
theArray[ back ] = x;
currentSize++;
}

/**
* Internal method to increment x with wraparound.
*/
template <class Object>
void Queue<Object>::increment( int & x )
{
if( ++x == theArray.size( ) )
x = 0;
}
TestQueueAr.cpp: Test program for queues

#include <iostream.h>
#include "QueueAr.h"
int main( )
{
Queue<int> q;

for( int j = 0; j < 5; j++ )


{
for( int i = 0; i < 5; i++ )
q.enqueue( i );

while( !q.isEmpty( ) )
cout << q.dequeue( ) << endl;
}

return 0;
}
BinarySearchTree.h: Header file for binary search tree
#ifndef BINARY_SEARCH_TREE_H_
#define BINARY_SEARCH_TREE_H_

#include "dsexceptions.h"
#include <iostream.h> // For NULL

// Binary node and forward declaration because g++ does


// not understand nested classes.
template <class Comparable>
class BinarySearchTree;

template <class Comparable>


class BinaryNode
{
Comparable element;
BinaryNode *left;
BinaryNode *right;

BinaryNode( const Comparable & theElement, BinaryNode *lt,


BinaryNode *rt )
: element( theElement ), left( lt ), right( rt ) { }
friend class BinarySearchTree<Comparable>;
};

// BinarySearchTree class
//
// CONSTRUCTION: with ITEM_NOT_FOUND object used to signal
failed finds
//
// ******************PUBLIC OPERATIONS*********************
// void insert( x ) --> Insert x
// void remove( x ) --> Remove x
// Comparable find( x ) --> Return item that matches x
// Comparable findMin( ) --> Return smallest item
// Comparable findMax( ) --> Return largest item
// boolean isEmpty( ) --> Return true if empty; else false
// void makeEmpty( ) --> Remove all items
// void printTree( ) --> Print tree in sorted order
template <class Comparable>
class BinarySearchTree
{
public:
explicit BinarySearchTree( const Comparable & notFound );
BinarySearchTree( const BinarySearchTree & rhs );
~BinarySearchTree( );

const Comparable & findMin( ) const;


const Comparable & findMax( ) const;
const Comparable & find( const Comparable & x ) const;
bool isEmpty( ) const;
void printTree( ) const;

void makeEmpty( );
void insert( const Comparable & x );
void remove( const Comparable & x );

const BinarySearchTree & operator=( const BinarySearchTree &


rhs );

private:
BinaryNode<Comparable> *root;
const Comparable ITEM_NOT_FOUND;

const Comparable & elementAt( BinaryNode<Comparable> *t )


const;

void insert( const Comparable & x, BinaryNode<Comparable> *


& t ) const;
void remove( const Comparable & x, BinaryNode<Comparable> *
& t ) const;
BinaryNode<Comparable> * findMin( BinaryNode<Comparable>
*t ) const;
BinaryNode<Comparable> * findMax( BinaryNode<Comparable>
*t ) const;
BinaryNode<Comparable> * find( const Comparable & x,
BinaryNode<Comparable> *t ) const;
void makeEmpty( BinaryNode<Comparable> * & t ) const;
void printTree( BinaryNode<Comparable> *t ) const;
BinaryNode<Comparable> * clone( BinaryNode<Comparable> *t )
const;
};

#include "BinarySearchTree.cpp"
#endif
BinarySearchTree.cpp: Implementation for binary search tree

#include "BinarySearchTree.h"
#include <iostream.h>

/**
* Implements an unbalanced binary search tree.
* Note that all "matching" is based on the < method.
*/
/**
* Construct the tree.
*/
template <class Comparable>
BinarySearchTree<Comparable>::BinarySearchTree( const Comparable
& notFound ) :
root( NULL ), ITEM_NOT_FOUND( notFound )
{
}

/**
* Copy constructor.
*/
template <class Comparable>
BinarySearchTree<Comparable>::
BinarySearchTree( const BinarySearchTree<Comparable> & rhs ) :
root( NULL ), ITEM_NOT_FOUND( rhs.ITEM_NOT_FOUND )
{
*this = rhs;
}

/**
* Destructor for the tree.
*/
template <class Comparable>
BinarySearchTree<Comparable>::~BinarySearchTree( )
{
makeEmpty( );
}

/**
* Insert x into the tree; duplicates are ignored.
*/
template <class Comparable>
void BinarySearchTree<Comparable>::insert( const Comparable &
x )
{
insert( x, root );
}

/**
* Remove x from the tree. Nothing is done if x is not found.
*/
template <class Comparable>
void BinarySearchTree<Comparable>::remove( const Comparable &
x )
{
remove( x, root );
}

/**
* Find the smallest item in the tree.
* Return smallest item or ITEM_NOT_FOUND if empty.
*/
template <class Comparable>
const Comparable & BinarySearchTree<Comparable>::findMin( )
const
{
return elementAt( findMin( root ) );
}

/**
* Find the largest item in the tree.
* Return the largest item of ITEM_NOT_FOUND if empty.
*/
template <class Comparable>
const Comparable & BinarySearchTree<Comparable>::findMax( )
const
{
return elementAt( findMax( root ) );
}

/**
* Find item x in the tree.
* Return the matching item or ITEM_NOT_FOUND if not found.
*/
template <class Comparable>
const Comparable & BinarySearchTree<Comparable>::
find( const Comparable & x ) const
{
return elementAt( find( x, root ) );
}

/**
* Make the tree logically empty.
*/
template <class Comparable>
void BinarySearchTree<Comparable>::makeEmpty( )
{
makeEmpty( root );
}

/**
* Test if the tree is logically empty.
* Return true if empty, false otherwise.
*/
template <class Comparable>
bool BinarySearchTree<Comparable>::isEmpty( ) const
{
return root == NULL;
}

/**
* Print the tree contents in sorted order.
*/
template <class Comparable>
void BinarySearchTree<Comparable>::printTree( ) const
{
if( isEmpty( ) )
cout << "Empty tree" << endl;
else
printTree( root );
}

/**
* Deep copy.
*/
template <class Comparable>
const BinarySearchTree<Comparable> &
BinarySearchTree<Comparable>::
operator=( const BinarySearchTree<Comparable> & rhs )
{
if( this != &rhs )
{
makeEmpty( );
root = clone( rhs.root );
}
return *this;
}

/**
* Internal method to get element field in node t.
* Return the element field or ITEM_NOT_FOUND if t is NULL.
*/
template <class Comparable>
const Comparable & BinarySearchTree<Comparable>::
elementAt( BinaryNode<Comparable> *t ) const
{
if( t == NULL )
return ITEM_NOT_FOUND;
else
return t->element;
}

/**
* Internal method to insert into a subtree.
* x is the item to insert.
* t is the node that roots the tree.
* Set the new root.
*/
template <class Comparable>
void BinarySearchTree<Comparable>::
insert( const Comparable & x, BinaryNode<Comparable> * & t )
const
{
if( t == NULL )
t = new BinaryNode<Comparable>( x, NULL, NULL );
else if( x < t->element )
insert( x, t->left );
else if( t->element < x )
insert( x, t->right );
else
; // Duplicate; do nothing
}

/**
* Internal method to remove from a subtree.
* x is the item to remove.
* t is the node that roots the tree.
* Set the new root.
*/
template <class Comparable>
void BinarySearchTree<Comparable>::
remove( const Comparable & x, BinaryNode<Comparable> * & t )
const
{
if( t == NULL )
return; // Item not found; do nothing
if( x < t->element )
remove( x, t->left );
else if( t->element < x )
remove( x, t->right );
else if( t->left != NULL && t->right != NULL ) // Two
children
{
t->element = findMin( t->right )->element;
remove( t->element, t->right );
}
else
{
BinaryNode<Comparable> *oldNode = t;
t = ( t->left != NULL ) ? t->left : t->right;
delete oldNode;
}
}

/**
* Internal method to find the smallest item in a subtree t.
* Return node containing the smallest item.
*/
template <class Comparable>
BinaryNode<Comparable> *
BinarySearchTree<Comparable>::findMin( BinaryNode<Comparable> *t
) const
{
if( t == NULL )
return NULL;
if( t->left == NULL )
return t;
return findMin( t->left );
}

/**
* Internal method to find the largest item in a subtree t.
* Return node containing the largest item.
*/
template <class Comparable>
BinaryNode<Comparable> *
BinarySearchTree<Comparable>::findMax( BinaryNode<Comparable> *t
) const
{
if( t != NULL )
while( t->right != NULL )
t = t->right;
return t;
}
/**
* Internal method to find an item in a subtree.
* x is item to search for.
* t is the node that roots the tree.
* Return node containing the matched item.
*/
template <class Comparable>
BinaryNode<Comparable> *
BinarySearchTree<Comparable>::
find( const Comparable & x, BinaryNode<Comparable> *t ) const
{
if( t == NULL )
return NULL;
else if( x < t->element )
return find( x, t->left );
else if( t->element < x )
return find( x, t->right );
else
return t; // Match
}
/****** NONRECURSIVE VERSION*************************
template <class Comparable>
BinaryNode<Comparable> *
BinarySearchTree<Comparable>::
find( const Comparable & x, BinaryNode<Comparable> *t ) const
{
while( t != NULL )
if( x < t->element )
t = t->left;
else if( t->element < x )
t = t->right;
else
return t; // Match

return NULL; // No match


}
*****************************************************/

/**
* Internal method to make subtree empty.
*/
template <class Comparable>
void BinarySearchTree<Comparable>::
makeEmpty( BinaryNode<Comparable> * & t ) const
{
if( t != NULL )
{
makeEmpty( t->left );
makeEmpty( t->right );
delete t;
}
t = NULL;
}

/**
* Internal method to print a subtree rooted at t in sorted
order.
*/
template <class Comparable>
void
BinarySearchTree<Comparable>::printTree( BinaryNode<Comparable> *t )
const
{
if( t != NULL )
{
printTree( t->left );
cout << t->element << endl;
printTree( t->right );
}
}

/**
* Internal method to clone subtree.
*/
template <class Comparable>
BinaryNode<Comparable> *
BinarySearchTree<Comparable>::clone( BinaryNode<Comparable> *
t ) const
{
if( t == NULL )
return NULL;
else
return new BinaryNode<Comparable>( t->element, clone( t-
>left ), clone( t->right ) );
}
TestBinarySearchTree.cpp: Test program for binary search tree

#include <iostream.h>
#include "BinarySearchTree.h"

// Test program
int main( )
{
const int ITEM_NOT_FOUND = -9999;
BinarySearchTree<int> t( ITEM_NOT_FOUND );
int NUMS = 4000;
const int GAP = 37;
int i;

cout << "Checking... (no more output means success)" <<


endl;

for( i = GAP; i != 0; i = ( i + GAP ) % NUMS )


t.insert( i );

for( i = 1; i < NUMS; i+= 2 )


t.remove( i );

if( NUMS < 40 )


t.printTree( );
if( t.findMin( ) != 2 || t.findMax( ) != NUMS - 2 )
cout << "FindMin or FindMax error!" << endl;

for( i = 2; i < NUMS; i+=2 )


if( t.find( i ) != i )
cout << "Find error1!" << endl;

for( i = 1; i < NUMS; i+=2 )


{
if( t.find( i ) != ITEM_NOT_FOUND )
cout << "Find error2!" << endl;
}

BinarySearchTree<int> t2( ITEM_NOT_FOUND );


t2 = t;

for( i = 2; i < NUMS; i+=2 )


if( t2.find( i ) != i )
cout << "Find error1!" << endl;

for( i = 1; i < NUMS; i+=2 )


{
if( t2.find( i ) != ITEM_NOT_FOUND )
cout << "Find error2!" << endl;
}

return 0;
}
AvlTree.h: Header file for AVL tree

#ifndef AVL_TREE_H_
#define AVL_TREE_H_

// Node and forward declaration because g++ does


// not understand nested classes.
template <class Comparable>
class AvlTree;

template <class Comparable>


class AvlNode
{
Comparable element;
AvlNode *left;
AvlNode *right;
int height;

AvlNode( const Comparable & theElement, AvlNode *lt, AvlNode


*rt, int h = 0 )
: element( theElement ), left( lt ), right( rt ),
height( h ) { }
friend class AvlTree<Comparable>;
};

#include "dsexceptions.h"
#include <iostream.h> // For NULL
// AvlTree class
//
// CONSTRUCTION: with ITEM_NOT_FOUND object used to signal
failed finds
//
// ******************PUBLIC OPERATIONS*********************
// void insert( x ) --> Insert x
// void remove( x ) --> Remove x (unimplemented)
// Comparable find( x ) --> Return item that matches x
// Comparable findMin( ) --> Return smallest item
// Comparable findMax( ) --> Return largest item
// boolean isEmpty( ) --> Return true if empty; else false
// void makeEmpty( ) --> Remove all items
// void printTree( ) --> Print tree in sorted order

template <class Comparable>


class AvlTree
{
public:
explicit AvlTree( const Comparable & notFound );
AvlTree( const AvlTree & rhs );
~AvlTree( );

const Comparable & findMin( ) const;


const Comparable & findMax( ) const;
const Comparable & find( const Comparable & x ) const;
bool isEmpty( ) const;
void printTree( ) const;

void makeEmpty( );
void insert( const Comparable & x );
void remove( const Comparable & x );

const AvlTree & operator=( const AvlTree & rhs );

private:
AvlNode<Comparable> *root;
const Comparable ITEM_NOT_FOUND;

const Comparable & elementAt( AvlNode<Comparable> *t )


const;

void insert( const Comparable & x, AvlNode<Comparable> * & t


) const;
AvlNode<Comparable> * findMin( AvlNode<Comparable> *t )
const;
AvlNode<Comparable> * findMax( AvlNode<Comparable> *t )
const;
AvlNode<Comparable> * find( const Comparable & x,
AvlNode<Comparable> *t ) const;
void makeEmpty( AvlNode<Comparable> * & t ) const;
void printTree( AvlNode<Comparable> *t ) const;
AvlNode<Comparable> * clone( AvlNode<Comparable> *t ) const;

// Avl manipulations
int height( AvlNode<Comparable> *t ) const;
int max( int lhs, int rhs ) const;
void rotateWithLeftChild( AvlNode<Comparable> * & k2 )
const;
void rotateWithRightChild( AvlNode<Comparable> * & k1 )
const;
void doubleWithLeftChild( AvlNode<Comparable> * & k3 )
const;
void doubleWithRightChild( AvlNode<Comparable> * & k1 )
const;
};

#include "AvlTree.cpp"
#endif
AvlTree.cpp: Implementation for AVL tree

#include "AvlTree.h"
#include <iostream.h>

/**
* Implements an unbalanced Avl search tree.
* Note that all "matching" is based on the compares method.
* @author Mark Allen Weiss
*/
/**
* Construct the tree.
*/
template <class Comparable>
AvlTree<Comparable>::AvlTree( const Comparable & notFound ) :
ITEM_NOT_FOUND( notFound ), root( NULL )
{
}

/**
* Copy constructor.
*/
template <class Comparable>
AvlTree<Comparable>::AvlTree( const AvlTree<Comparable> &
rhs ) :
ITEM_NOT_FOUND( rhs.ITEM_NOT_FOUND ), root( NULL )
{
*this = rhs;
}

/**
* Destructor for the tree.
*/
template <class Comparable>
AvlTree<Comparable>::~AvlTree( )
{
makeEmpty( );
}

/**
* Insert x into the tree; duplicates are ignored.
*/
template <class Comparable>
void AvlTree<Comparable>::insert( const Comparable & x )
{
insert( x, root );
}

/**
* Remove x from the tree. Nothing is done if x is not found.
*/
template <class Comparable>
void AvlTree<Comparable>::remove( const Comparable & x )
{
cout << "Sorry, remove unimplemented; " << x <<
" still present" << endl;
}

/**
* Find the smallest item in the tree.
* Return smallest item or ITEM_NOT_FOUND if empty.
*/
template <class Comparable>
const Comparable & AvlTree<Comparable>::findMin( ) const
{
return elementAt( findMin( root ) );
}

/**
* Find the largest item in the tree.
* Return the largest item of ITEM_NOT_FOUND if empty.
*/
template <class Comparable>
const Comparable & AvlTree<Comparable>::findMax( ) const
{
return elementAt( findMax( root ) );
}

/**
* Find item x in the tree.
* Return the matching item or ITEM_NOT_FOUND if not found.
*/
template <class Comparable>
const Comparable & AvlTree<Comparable>::
find( const Comparable & x ) const
{
return elementAt( find( x, root ) );
}

/**
* Make the tree logically empty.
*/
template <class Comparable>
void AvlTree<Comparable>::makeEmpty( )
{
makeEmpty( root );
}

/**
* Test if the tree is logically empty.
* Return true if empty, false otherwise.
*/
template <class Comparable>
bool AvlTree<Comparable>::isEmpty( ) const
{
return root == NULL;
}

/**
* Print the tree contents in sorted order.
*/
template <class Comparable>
void AvlTree<Comparable>::printTree( ) const
{
if( isEmpty( ) )
cout << "Empty tree" << endl;
else
printTree( root );
}

/**
* Deep copy.
*/
template <class Comparable>
const AvlTree<Comparable> &
AvlTree<Comparable>::
operator=( const AvlTree<Comparable> & rhs )
{
if( this != &rhs )
{
makeEmpty( );
root = clone( rhs.root );
}
return *this;
}

/**
* Internal method to get element field in node t.
* Return the element field or ITEM_NOT_FOUND if t is NULL.
*/
template <class Comparable>
const Comparable &
AvlTree<Comparable>::elementAt( AvlNode<Comparable> *t ) const
{
if( t == NULL )
return ITEM_NOT_FOUND;
else
return t->element;
}

/**
* Internal method to insert into a subtree.
* x is the item to insert.
* t is the node that roots the tree.
*/
template <class Comparable>
void AvlTree<Comparable>::insert( const Comparable & x,
AvlNode<Comparable> * & t ) const
{
if( t == NULL )
t = new AvlNode<Comparable>( x, NULL, NULL );
else if( x < t->element )
{
insert( x, t->left );
if( height( t->left ) - height( t->right ) == 2 )
if( x < t->left->element )
rotateWithLeftChild( t );
else
doubleWithLeftChild( t );
}
else if( t->element < x )
{
insert( x, t->right );
if( height( t->right ) - height( t->left ) == 2 )
if( t->right->element < x )
rotateWithRightChild( t );
else
doubleWithRightChild( t );
}
else
; // Duplicate; do nothing
t->height = max( height( t->left ), height( t->right ) ) +
1;
}

/**
* Internal method to find the smallest item in a subtree t.
* Return node containing the smallest item.
*/
template <class Comparable>
AvlNode<Comparable> *
AvlTree<Comparable>::findMin( AvlNode<Comparable> *t ) const
{
if( t == NULL)
return t;

while( t->left != NULL )


t = t->left;
return t;
}

/**
* Internal method to find the largest item in a subtree t.
* Return node containing the largest item.
*/
template <class Comparable>
AvlNode<Comparable> *
AvlTree<Comparable>::findMax( AvlNode<Comparable> *t ) const
{
if( t == NULL )
return t;

while( t->right != NULL )


t = t->right;
return t;
}

/**
* Internal method to find an item in a subtree.
* x is item to search for.
* t is the node that roots the tree.
* Return node containing the matched item.
*/
template <class Comparable>
AvlNode<Comparable> *
AvlTree<Comparable>::find( const Comparable & x,
AvlNode<Comparable> *t ) const
{
while( t != NULL )
if( x < t->element )
t = t->left;
else if( t->element < x )
t = t->right;
else
return t; // Match

return NULL; // No match


}

/**
* Internal method to make subtree empty.
*/
template <class Comparable>
void AvlTree<Comparable>::makeEmpty( AvlNode<Comparable> * & t )
const
{
if( t != NULL )
{
makeEmpty( t->left );
makeEmpty( t->right );
delete t;
}
t = NULL;
}

/**
* Internal method to clone subtree.
*/
template <class Comparable>
AvlNode<Comparable> *
AvlTree<Comparable>::clone( AvlNode<Comparable> * t ) const
{
if( t == NULL )
return NULL;
else
return new AvlNode<Comparable>( t->element, clone( t-
>left ),
clone( t->right ), t-
>height );
}
/**
* Return the height of node t or -1 if NULL.
*/
template <class Comparable>
int AvlTree<Comparable>::height( AvlNode<Comparable> *t ) const
{
return t == NULL ? -1 : t->height;
}

/**
* Return maximum of lhs and rhs.
*/
template <class Comparable>
int AvlTree<Comparable>::max( int lhs, int rhs ) const
{
return lhs > rhs ? lhs : rhs;
}

/**
* Rotate binary tree node with left child.
* For AVL trees, this is a single rotation for case 1.
* Update heights, then set new root.
*/
template <class Comparable>
void
AvlTree<Comparable>::rotateWithLeftChild( AvlNode<Comparable> * & k2 )
const
{
AvlNode<Comparable> *k1 = k2->left;
k2->left = k1->right;
k1->right = k2;
k2->height = max( height( k2->left ), height( k2->right ) )
+ 1;
k1->height = max( height( k1->left ), k2->height ) + 1;
k2 = k1;
}

/**
* Rotate binary tree node with right child.
* For AVL trees, this is a single rotation for case 4.
* Update heights, then set new root.
*/
template <class Comparable>
void
AvlTree<Comparable>::rotateWithRightChild( AvlNode<Comparable> * & k1 )
const
{
AvlNode<Comparable> *k2 = k1->right;
k1->right = k2->left;
k2->left = k1;
k1->height = max( height( k1->left ), height( k1->right ) )
+ 1;
k2->height = max( height( k2->right ), k1->height ) + 1;
k1 = k2;
}
/**
* Double rotate binary tree node: first left child.
* with its right child; then node k3 with new left child.
* For AVL trees, this is a double rotation for case 2.
* Update heights, then set new root.
*/
template <class Comparable>
void
AvlTree<Comparable>::doubleWithLeftChild( AvlNode<Comparable> * & k3 )
const
{
rotateWithRightChild( k3->left );
rotateWithLeftChild( k3 );
}

/**
* Double rotate binary tree node: first right child.
* with its left child; then node k1 with new right child.
* For AVL trees, this is a double rotation for case 3.
* Update heights, then set new root.
*/
template <class Comparable>
void
AvlTree<Comparable>::doubleWithRightChild( AvlNode<Comparable> * & k1 )
const
{
rotateWithLeftChild( k1->right );
rotateWithRightChild( k1 );
}

/**
* Internal method to print a subtree in sorted order.
* t points to the node that roots the tree.
*/
template <class Comparable>
void AvlTree<Comparable>::printTree( AvlNode<Comparable> *t )
const
{
if( t != NULL )
{
printTree( t->left );
cout << t->element << endl;
printTree( t->right );
}
}

TestAvlTree.cpp: Test program for AVL trees

#include <iostream.h>
#include "AvlTree.h"

// Test program
int main( )
{
const int ITEM_NOT_FOUND = -9999;
AvlTree<int> t( ITEM_NOT_FOUND ), t2( ITEM_NOT_FOUND );
int NUMS = 40000;
const int GAP = 37;
int i;

cout << "Checking... (no more output means success)" <<


endl;

for( i = GAP; i != 0; i = ( i + GAP ) % NUMS )


t.insert( i );

if( NUMS < 40 )


t.printTree( );
if( t.findMin( ) != 1 || t.findMax( ) != NUMS - 1 )
cout << "FindMin or FindMax error!" << endl;

t2 = t;

for( i = 1; i < NUMS; i++ )


if( t2.find( i ) != i )
cout << "Find error1!" << endl;
if( t2.find( 0 ) != ITEM_NOT_FOUND )
cout << "ITEM_NOT_FOUND failed!" << endl;

return 0;
}
Source Code for Data Structures and
Algorithm Analysis in C++ (Second
Edition)
Here is the source code for Data Structures and Algorithm Analysis in C++ (Second
Edition), by Mark Allen Weiss. The materials here are copyrighted.

I have successfully compiled and tested the programs under Borland 5.0, Visual C+
+ 5.0 and 6.0, CodeWarrior Pro Release 2 (Windows), g++ 2.7.2 and 2.8.1, and
SunPro 4.1. Greg Ozbirn from U.T. Dallas has rewritten the code using ANSI C++.
This mostly involves fixing the header files. Click here to obtain the ANSI C++
conversion

Known Bugs
 TestCursorList.cpp does not compile under g++ 2.7.2. I think it is a problem
with static template members, which g++ does not understand until g++ 2.8.1.
 Metrowerks insists on compiling the STL, which causes conflicts for swap and
merge in Sort.h. Also, it does not understand default template parameters,
making its vector and string incompatible with some of the code. The easy fix
is to add preprocessor macros as follows: in vector.h, #define vector
Vector; similarly for string.h and in Sort.h. This works as long as
iostream.h is included prior to the other header files, as is done in the online
code.

Compilation Instructions
Here are compilation instructions for g++, SunPro, Borland 5.0, and Visual 5.0. (How to
setup Windows for Visual command line compilation.) You can use this to guide you on
how to generate project files for Visual C++. Throughout I am assuming 32-bit ints. All
template classes have the header file include the .cpp file, even though this defeats the
purpose of separate compilation. There are ways around this, but I'd rather keep
everything simple for now. Jeffrey Walton has supplied some common workarounds for
C++ compilers. Finally, here is a zip file that contains CodeWarrior projects. You'll have
to get everything in the correct directories. (Does not include some late additions from
Chapter 1; check back later).

Complete Bundle
 Unix tar | gzip
 Unix tar (Winzip can read this.)
 Note to Macintosh users: There is a utility to read zip files. Click here to
download.

Individual Files
mystring.h: If you don't have a string type

string.cpp: If you don't have a string type

vector.h: If you don't have a vector type

vector.cpp: If you don't have a vector type

matrix.h: Simple matrix class

dsexceptions.h: Simple exception classes

Fig01_02.cpp: A simple recursive routine with a test program

Fig01_03.cpp: An example of infinite recursion

Fig01_04.cpp: Recursive routine to print numbers, with a test program

Fig01_05.cpp: Simplest IntCell class, with a test program


Fig01_06.cpp: IntCell class with a few extras, with a test program

IntCell.h: IntCell class interface (Fig 1.7)

IntCell.cpp: IntCell class implementation (Fig 1.8)

TestIntCell.cpp: IntCell test program (Fig 1.9)

Fig01_10.cpp: Illustration of using the vector class

Fig01_11.cpp: Dynamically allocating an IntCell object (lame)

BuggyIntCell.cpp: Buggy IntCell class implementation (Figs 1.14 and 1.15)

Fig01_16.cpp: IntCell class with pointers and Big Three

FindMax.cpp: Function template FindMax (Figs 1.17 and 1.18)

Fig01_19.cpp: MemoryCell class template without separation

MemoryCell.h: MemoryCell class interface (Fig 1.20)

MemoryCell.cpp: MemoryCell class implementation (Fig 1.21)

TestMemoryCell.cpp: MemoryCell test program (Fig 1.22)

Fig01_23.cpp: Using Comparable templates: Employee class example

MaxSumTest.cpp: Various maximum subsequence sum algorithms

Fig02_09.cpp: Test program for binary search

Fig02_10.cpp: Euclid's algorithm, with a test program

Fig02_11.cpp: Recursive exponentiation algorithm, with a test program

LinkedList.h: Header file for linked list

LinkedList.cpp: Implementation for linked list

TestLinkedList.cpp: Test program for linked list package

Polynomial.cpp: Polynomials

CursorList.h: Header file for cursor linked list


CursorList.cpp: Implementation for cursor linked list

TestCursorList.cpp: Test program for cursor implementation of linked lists

StackAr.h: Header file for stack: array version

StackAr.cpp: Implementation for stack: array version

TestStackAr.cpp: Test program for (array-based) stacks

StackLi.h: Header file for stack: list version

StackLi.cpp: Implementation for stack: list version

TestStackLi.cpp: Test program for (list-based) stacks

QueueAr.h: Header file for queue: array version

QueueAr.cpp: Implementation for queue: array version

TestQueueAr.cpp: Test program for queues

BinarySearchTree.h: Header file for binary search tree

BinarySearchTree.cpp: Implementation for binary search tree

TestBinarySearchTree.cpp: Test program for binary search tree

AvlTree.h: Header file for AVL tree

AvlTree.cpp: Implementation for AVL tree

TestAvlTree.cpp: Test program for AVL trees

SeparateChaining.h: Header file for separate chaining

SeparateChaining.cpp: Implementation for separate chaining

TestSeparateChaining.cpp: Test program for separate chaining hash tables

QuadraticProbing.h: Header file for quadratic probing hash table

QuadraticProbing.cpp: Implementation for quadratic probing hash table

TestQuadraticProbing.cpp: Test program for quadratic probing hash tables


BinaryHeap.h: Header file for binary heap

BinaryHeap.cpp: Implementation for binary heap

TestBinaryHeap.cpp: Test program for binary heaps

LeftistHeap.h: Header file for leftist heap

LeftistHeap.cpp: Implementation for leftist heap

TestLeftistHeap.cpp: Test program for leftist heaps

BinomialQueue.h: Header file for binomial queue

BinomialQueue.cpp: Implementation for binomial queue

TestBinomialQueue.cpp: Test program for binomial queues

Sort.h: A collection of sorting and selection routines

TestSort.cpp: Test program for sorting and selection routines

DisjSets.h: Header file for disjoint sets algorithms

DisjSets.cpp: Efficient implementation of disjoint sets algorithm

TestFastDisjSets.cpp: Test program for disjoint sets algorithm

Fig10_38.cpp: Simple matrix multiplication algorithm with a test program

Fig10_40.cpp: Algorithms to compute Fibonacci numbers

Fig10_43.cpp: Inefficient recursive algorithm (see text)

Fig10_45.cpp: Better algorithm to replace fig10_43.c (see text)

Fig10_46.cpp: Dynamic programming algorithm for optimal chain matrix multiplication,


with a test program

Fig10_53.cpp: All-pairs algorithm, with a test program

Random.h: Header file for random number class

Random.cpp: Implementation for random number class

TestRandom.cpp: Test program for random number class


Fig10_62.cpp: Randomized primality testing algorithm, with a test program

SplayTree.h: Header file for top-down splay tree

SplayTree.cpp: Implementation for top-down splay tree

TestSplayTree.cpp: Test program for splay trees

DSL.h: Header file for deterministic skip list

DSL.cpp: Implementation for deterministic skip list

TestDSL.cpp: Test program for determinstic skip lists

RedBlackTree.h: Header file for top-down red black tree

RedBlackTree.cpp: Implementation for top-down red black tree

TestRedBlackTree.cpp: Test program for red black trees

Treap.h: Header file for treap

Treap.cpp: Implementation for treap

TestTreap.cpp: Test program for treap

AATree.h: Header file for AA-tree

AATree.cpp: Implementation for AA-tree

TestAATree.cpp: Test program for AA-trees

KdTree.cpp: Implementation and test program for k-d trees

PairingHeap.h: Header file for pairing heap

PairingHeap.cpp: Implementation for pairing heap

TestPairingHeap.cpp: Test program for pairing heaps

FigA_04.cpp: Example of push_back with vectors

FigA_05.cpp: Queue implemented with STL list

FigA_06.cpp: Example of set with reverse order


Concordance1.cpp: Concordance program using STL

Concordance2.cpp: Concordance program not using STL

Graph1.cpp: Shortest path program using STL

Graph2.cpp: Shortest path program not using STL

You might also like