Date post: | 18-Nov-2014 |
Category: |
Documents |
Upload: | venkat05091990 |
View: | 1,177 times |
Download: | 3 times |
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