Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition,
© 2005 Pearson Education, Inc. All rights reserved. 0-13-140909-3
Figure 6.1A List.h Using Static Array |
/*-- List.h --------------------------------------------------------------- This header file defines the data type List for processing lists. Basic operations are: Constructor empty: Check if list is empty insert: Insert an item erase: Remove an item display: Output the list <<, >> : input and output operators -------------------------------------------------------------------------*/ #include <iostream> #ifndef LIST #define LIST const int CAPACITY = 1024; typedef int ElementType; class List { public: /******** Function Members ********/ /***** Class constructor *****/ List(); /*---------------------------------------------------------------------- Construct a List object. Precondition: None Postcondition: An empty List object has been constructed; mySize is 0. -----------------------------------------------------------------------*/ /***** empty operation *****/ bool empty() const; /*---------------------------------------------------------------------- Check if a list is empty. Precondition: None Postcondition: true is returned if the list is empty, false if not. -----------------------------------------------------------------------*/ /***** insert and erase *****/ void insert(ElementType item, int pos); /*---------------------------------------------------------------------- Insert a value into the list at a given position. Precondition: item is the value to be inserted; there is room in the array (mySize < CAPACITY); and the position satisfies 0 <= pos <= mySize. Postcondition: item has been inserted into the list at the position determined by pos (provided there is room and pos is a legal position). -----------------------------------------------------------------------*/ void erase(int pos); /*---------------------------------------------------------------------- Remove a value from the list at a given position. Precondition: The list is not empty and the position satisfies 0 <= pos < mySize. Postcondition: element at the position determined by pos has been removed (provided pos is a legal position). ----------------------------------------------------------------------*/ /***** output *****/ void display(ostream & out) const; /*---------------------------------------------------------------------- Display a list. Precondition: out is a reference parameter Postcondition: The list represented by this List object has been inserted into ostream out. -----------------------------------------------------------------------*/ private: /******** Data Members ********/ int mySize; // current size of list stored in myArray ElementType myArray[CAPACITY]; // array to store list elements }; //--- end of List class //------ Prototype of output operator ostream & operator<< (ostream & out, const List & aList); #endif |
Figure 6.1B List.cpp Using Static Array |
/*-- List.cpp------------------------------------------------------------ This file implements List member functions. -------------------------------------------------------------------------*/ #include <cassert> using namespace std; #include "List.h" //--- Definition of class constructor List::List() : mySize(0) { } //--- Definition of empty() bool List::empty() const { return mySize == 0; } //--- Definition of display() void List::display(ostream & out) const { for (int i = 0; i < mySize; i++) out << myArray[i] << " "; } //--- Definition of output operator ostream & operator<< (ostream & out, const List & aList) { aList.display(out); return out; } //--- Definition of insert() void List::insert(ElementType item, int pos) { if (mySize == CAPACITY) { cerr << "*** No space for list element -- terminating " "execution ***\n"; exit(1); } if (pos < 0 || pos > mySize) { cerr << "*** Illegal location to insert -- " << pos << ". List unchanged. ***\n"; return; } // First shift array elements right to make room for item for(int i = mySize; i > pos; i--) myArray[i] = myArray[i - 1]; // Now insert item at position pos and increase list size myArray[pos] = item; mySize++; } // Definition of erase() void List::erase(int pos) { if (mySize == 0) { cerr << "*** List is empty ***\n"; return; } if (pos < 0 || pos >= mySize) { cerr << "Illegal location to delete -- " << pos << ". List unchanged. ***\n"; return; } // Shift array elements left to close the gap for(int i = pos; i < mySize; i++) myArray[i] = myArray[i + 1]; // Decrease list size mySize--; } |
Figure 6.1C List Test Program |
//--- Program to test List class. #include <iostream> using namespace std; #include "List.h" int main() { // Test the class constructor List intList; cout << "Constructing intList\n"; // Test empty() and output of empty list if (intList.empty()) cout << "Empty List: \n" << intList << endl; // Test output of empty list // Test insert() for (int i = 0; i < 9; i++) { cout << "Inserting " << i << " at position " << i/2 << endl; intList.insert(i, i/2); // -- Insert i at position i/2 //Test output cout << intList << endl; } cout << "List empty? " << (intList.empty() ? "Yes" : "No") << endl; cout << "\nTry to insert at position -1" << endl; intList.insert(0, -1); cout << "\nTry to insert at position 10" << endl; intList.insert(0, 10); // Test erase int index; cout << endl; while (!intList.empty()) { cout << "Give an index of a list element to remove: "; cin >> index; intList.erase(index); cout << intList << endl; } cout << "List is empty" << endl; cout << "\nInserting " << CAPACITY<< " integers\n"; for (int i = 0; i < CAPACITY; i++) intList.insert(i, i); cout << "Attempting to insert one more integer:\n"; intList.insert(-1, 0); return 0; } |
Figure 6.2A List.h With Dynamic Allocation |
/*-- List.h --------------------------------------------------------------- This header file defines the data type List for processing lists. Basic operations are: Constructor Destructor Copy constructor Assignment operator empty: Check if list is empty insert: Insert an item erase: Remove an item display: Output the list << : Output operator -------------------------------------------------------------------------*/ #include <iostream> #ifndef LIST #define LIST typedef int ElementType; class List { public: /******** Function Members ********/ /***** Class constructor *****/ List(int maxSize = 1024); /*---------------------------------------------------------------------- Construct a List object. Precondition: maxSize is a positive integer with default value 1024. Postcondition: An empty List object is constructed; myCapacity == maxSize (default value 1024); myArrayPtr points to a run-time array with myCapacity as its capacity; and mySize is 0. -----------------------------------------------------------------------*/ /***** Class destructor *****/ ~List(); /*---------------------------------------------------------------------- Destroys a List object. Precondition: The life of a List object is over. Postcondition: The memory dynamically allocated by the constructor for the array pointed to by myArrayPtr has been returned to the heap. ------------------------------------------------------------------*/ /***** Copy constructor *****/ List(const List & origList); /*---------------------------------------------------------------------- Construct a copy of a List object. Precondition: A copy of origList is needed; origList is a const reference parameter. Postcondition: A copy of origList has been constructed. -----------------------------------------------------------------------*/ /***** Assignment operator *****/ List & operator=(const List & origList); /*---------------------------------------------------------------------- Assign a copy of a List object to the current object. Precondition: none Postcondition: A copy of origList has been assigned to this object. A reference to this list is returned. -----------------------------------------------------------------------*/ /***** empty operation *****/ bool empty() const; /*---------------------------------------------------------------------- Check if a list is empty. Precondition: None Postcondition: true is returned if the list is empty, false if not. -----------------------------------------------------------------------*/ /***** insert and erase *****/ void insert(ElementType item, int pos); /*---------------------------------------------------------------------- Insert a value into the list at a given position. Precondition: item is the value to be inserted; there is room in the array (mySize < CAPACITY); and the position satisfies 0 <= pos <= mySize. Postcondition: item has been inserted into the list at the position determined by pos (provided there is room and pos is a legal position). -----------------------------------------------------------------------*/ void erase(int pos); /*---------------------------------------------------------------------- Remove a value from the list at a given position. Precondition: The list is not empty and the position satisfies 0 <= pos < mySize. Postcondition: element at the position determined by pos has been removed (provided pos is a legal position). ----------------------------------------------------------------------*/ /***** output *****/ void display(ostream & out) const; /*---------------------------------------------------------------------- Display a list. Precondition: The ostream out is open. Postcondition: The list represented by this List object has been inserted into out. -----------------------------------------------------------------------*/ private: /******** Data Members ********/ int mySize; // current size of list stored in array int myCapacity; // capacity of array ElementType * myArrayPtr; // pointer to dynamically-allocated array }; //--- end of List class //------ Prototype of output operator ostream & operator<< (ostream & out, const List & aList); #endif |
Figure 6.2B List.cpp With Dynamic Allocation |
/*-- List.cpp------------------------------------------------------------ This file implements List member functions. -------------------------------------------------------------------------*/ #include <cassert> #include <new> using namespace std; #include "List.h" //--- Definition of class constructor List::List(int maxSize) : mySize(0), myCapacity(maxSize) { myArrayPtr = new(nothrow) ElementType[maxSize]; assert(myArrayPtr != 0); } //--- Definition of class destructor List::~List() { delete [] myArrayPtr; } //--- Definition of the copy constructor List::List(const List & origList) : mySize(origList.mySize), myCapacity(origList.myCapacity) { //--- Get new array for copy myArrayPtr = new(nothrow) ElementType[myCapacity]; if (myArrayPtr != 0) // check if memory available //--- Copy origList's array into this new array for(int i = 0; i < myCapacity; i++) myArrayPtr[i] = origList.myArrayPtr[i]; else { cerr << "*Inadequate memory to allocate stack ***\n"; exit(1); } } //--- Definition of the assignment operator List & List::operator=(const List & origList) { if (this != &origList) // check for list = list { mySize = origList.mySize; myCapacity = origList.myCapacity; //-- Allocate a new array if necessary if (myCapacity != origList.myCapacity) { delete[] myArrayPtr; myArrayPtr = new(nothrow) ElementType[myCapacity]; if (myArrayPtr == 0) // check if memory available { cerr << "*Inadequate memory to allocate stack ***\n"; exit(1); } } //--- Copy origList's array into this new array for(int i = 0; i < myCapacity; i++) myArrayPtr[i] = origList.myArrayPtr[i]; } return *this; } //--- Definition of empty() bool List::empty() const { return mySize == 0; } //--- Definition of display() void List::display(ostream & out) const { for (int i = 0; i < mySize; i++) out << myArrayPtr[i] << " "; } //--- Definition of output operator ostream & operator<< (ostream & out, const List & aList) { aList.display(out); return out; } //--- Definition of insert() void List::insert(ElementType item, int pos) { if (mySize == myCapacity) { cerr << "*** No space for list element -- terminating " "execution ***\n"; exit(1); } if (pos < 0 || pos > mySize) { cerr << "*** Illegal location to insert -- " << pos << ". List unchanged. ***\n"; return; } // First shift array elements right to make room for item for(int i = mySize; i > pos; i--) myArrayPtr[i] = myArrayPtr[i - 1]; // Now insert item at position pos and increase list size myArrayPtr[pos] = item; mySize++; } //--- Definition of erase() void List::erase(int pos) { if (mySize == 0) { cerr << "*** List is empty ***\n"; return; } if (pos < 0 || pos >= mySize) { cerr << "Illegal location to delete -- " << pos << ". List unchanged. ***\n"; return; } // Shift array elements left to close the gap for(int i = pos; i < mySize; i++) myArrayPtr[i] = myArrayPtr[i + 1]; // Decrease list size mySize--; } |
Figure 6.2C List Testing Program |
/* listtester.cpp is a program for testing class List. */ #include <iostream> using namespace std; #include "List.h" // f() is a function with void f(List aList) // List value parameter { // to test the copy constructor for (int i = 1; i < 5; i++) { aList.insert(100*i, i); // insert into the copy cout << aList << endl; // output the copy } } int main() { // Test the class constructor List intList; cout << "Constructing intList\n"; // Test empty() and output of empty list if (intList.empty()) cout << "Empty List: \n" << intList << endl; // Test output of empty list // Test insert() for (int i = 0; i < 9; i++) { intList.insert(i, i/2); // -- Insert i at position i/2 //Test output cout << intList << endl; } cout << "List empty? " << (intList.empty() ? "Yes" : "No") << endl; // Test destructor { List anotherList; for (int i = 0; i < 10; i++) anotherList.insert(100*i, i); cout << "\nHere's another list:\n" << anotherList << endl; cout << "Now destroying this list\n"; } // Test the copy constructor cout << "\n\n"; f(intList); cout << "\n\nOriginal list:"; // Output the original to make cout << intList<< endl; // sure it hasn't been changed // Test erase int index; while (!intList.empty()) { cout << "Give an index of list element to remove: "; cin >> index; intList.erase(index); cout << intList << endl; } cout << "List is empty" << endl; } |
Figure 6.3 Calls to Constructors and Destructor |
/*------------------------------------------------------------------------- This program demonstrates how often a class's constructor, destructor, and copy constructor can get called automatically by the compiler. It uses the List class from Fig. 4.2 but with output statements inserted into the constructor, destructor, and copy constructor to trace when they are called. -------------------------------------------------------------------------*/ #include <iostream> using namespace std; #include "List.h" void print (List aList) /*------------------------------------------------------------------------- Function to print a list. Precondition: aList is a value parameter Postcondition: Contents of aList have been displayed -------------------------------------------------------------------------*/ { cout << aList << endl; } int main() { int listLimit; cout << "Enter maximum number of list elements: "; cin >> listLimit; cout << "\n*** Next Statement: List list1(listLimit);\n"; List list1(listLimit); for (int i = 0; i <= 4; i++) { cout << "*** Next Statement: list1.insert(i, i);\n"; list1.insert(i, i); } cout << "\n*** Next Statement: List list2 = list1;\n"; List list2 = list1; cout << "\n*** Next Statement: print(list2);\n"; print(list2); cout << "\n*** Next Statement: List list3;\n"; List list3; cout << "\n*** Next Statement: list3 = list2;\n"; list3 = list2; cout << "\n*** Next Statement: print(list3);\n"; print(list3); cout << "\n*** Next Statement: return 0;\n"; return 0; } |
Figure |
|
Figure |
|
Figure |
|
Figure |
|
Figure |
|
Figure |
|
Figure |
|
Figure |
|
Figure |
|
Figure |
|
Figure |
|
Figure |
|