32
Carrano - Chapter 3 CS 150 1 List Abstract Data Types We have reached the point where we can customize our own versions of list types that do not encounter the problems we normally associate with traditional C++ arrays. We’d like to be able to do the following: Pass a list by value to a function! Have a function that returns a list! Assign a list a new value with an assignment statement! Insert a new element in the list at a particular location, and have the list make room for the new element! Remove an element from the list, and have the list adjust the subsequent elements so there’s no gap between elements! Access a list element at a particular position without “crashing” if the index is inappropriate! Access the first element at position #1 and the last element at position #length!

Carrano - Chapter 3CS 150141 List Abstract Data Types We have reached the point where we can customize our own versions of list types that do not encounter

Embed Size (px)

Citation preview

Carrano - Chapter 3 CS 150 1

List Abstract Data Types

We have reached the point where we can customize our own versions of list types that do not encounter the problems we normally associate with traditional C++ arrays.

We’d like to be able to do the following:

•Pass a list by value to a function!

•Have a function that returns a list!

•Assign a list a new value with an assignment statement!

•Insert a new element in the list at a particular location, and have the list make room for the new element!

•Remove an element from the list, and have the list adjust the subsequent elements so there’s no gap between elements!

•Access a list element at a particular position without “crashing” if the index is inappropriate!

•Access the first element at position #1 and the last element at position #length!

Carrano - Chapter 3 CS 150 2

To Start Out: A New PhoneListing Class

/////////////////////////////////////////////////////// phoneListing.h //// The class definition for the PhoneListing class ///////////////////////////////////////////////////////#ifndef PHONE_LISTING_H

#include <iostream>#include <string>

using namespace std;class PhoneListing{ public: // Constructor PhoneListing(); PhoneListing(string newName, string newPhoneNumber);

// Member functions void setName(string newName); void setPhoneNumber(string newPhoneNumber);

// Overloaded operators PhoneListing& operator = (const PhoneListing &listing); bool operator == (PhoneListing listing); bool operator < (PhoneListing listing); bool operator <= (PhoneListing listing); bool operator > (PhoneListing listing); bool operator >= (PhoneListing listing); bool operator != (PhoneListing listing);

Carrano - Chapter 3 CS 150 3

phoneListing.h (Continued)

// Accessor functions string getName() const; string getPhoneNumber() const;

// Friend functions friend istream& operator >> (istream &sourceFileStream, PhoneListing &listing); friend ostream& operator << (ostream &destinationFileStream, const PhoneListing &listing);

private: // Data members string name; string phoneNumber;};

#define PHONE_LISTING_H#endif

Carrano - Chapter 3 CS 150 4

phoneListing.cpp

//////////////////////////////////////////////////////////// phoneListing.cpp //// The class implementation for the PhoneListing class. ////////////////////////////////////////////////////////////#include <iostream>#include <string>#include "phoneListing.h"

using namespace std;

// This default constructor sets up the data members with no values. //PhoneListing::PhoneListing(){}

// This initializing constructor sets up the data members in the obvious way. //PhoneListing::PhoneListing(string newName, string newPhoneNumber){ name = newName; phoneNumber = newPhoneNumber;}

// This member function sets the PhoneListing's name //// data member to the parameterized value. //void PhoneListing::setName(string newName){ name = newName; return;}

Carrano - Chapter 3 CS 150 5

phoneListing.cpp (Continued)// This member function sets the PhoneListing's phoneNumber //// data member to the parameterized value. //void PhoneListing::setPhoneNumber(string newPhoneNumber){ phoneNumber = newPhoneNumber; return;}

// Assignment operator: sets both data members of *this to copies //// of their counterparts in the parameterized PhoneListing. //PhoneListing& PhoneListing::operator = (const PhoneListing &listing){ name = listing.name; phoneNumber = listing.phoneNumber; return *this;}

// Equality operator: based upon equality between PhoneListings' name values. //bool PhoneListing::operator == (PhoneListing listing){ return (name == listing.name);}

// Less-than operator: based upon whether name value of *this //// is less than name value of parameterized PhoneListing. //bool PhoneListing::operator < (PhoneListing listing){ return (name < listing.name);}

Carrano - Chapter 3 CS 150 6

phoneListing.cpp (Continued)

// Less-than-or-equal-to operator: based upon whether name value of *this //// is less than or equal to name value of parameterized PhoneListing. //bool PhoneListing::operator <= (PhoneListing listing){ return (name <= listing.name);}

// Greater-than operator: based upon whether name value of *this //// is greater than name value of parameterized PhoneListing. //bool PhoneListing::operator > (PhoneListing listing){ return (name > listing.name);}

// Greater-than-or-equal-to operator: based upon whether name value of *this //// is greater than or equal to name value of parameterized PhoneListing. //bool PhoneListing::operator >= (PhoneListing listing){ return (name >= listing.name);}

// Inequality operator: based upon inequality between PhoneListings' name values. //bool PhoneListing::operator != (PhoneListing listing){ return (name != listing.name);}

Carrano - Chapter 3 CS 150 7

phoneListing.cpp (Continued)

// Accessor function for the value of the name data member. //string PhoneListing::getName() const{ return name;}

// Accessor function for the value of the phoneNumber data member. //string PhoneListing::getPhoneNumber() const{ return phoneNumber;}

// Input operator for the PhoneListing class: retrieves //// name value, followed by phoneNumber value. //istream& operator >> (istream &inputFileStream, PhoneListing &listing){ inputFileStream >> listing.name >> listing.phoneNumber; return inputFileStream;}

// Output operator for the PhoneListing class: outputs //// name value, followed by phoneNumber value. //ostream& operator << (ostream &outputFileStream, const PhoneListing &listing){ outputFileStream << listing.name << ": " << listing.phoneNumber; return outputFileStream;}

Carrano - Chapter 3 CS 150 8

Now Let’s Set Up Our Own List Class!/////////////////////////////////////////////// list.h //// The class definition for the List class ///////////////////////////////////////////////#ifndef LIST_H

#include <iostream>#include <string>#include "phoneListing.h"

using namespace std;

const int MAX_LIST_SIZE = 100;

typedef PhoneListing elementType;

class List{ public: // Class constructors List(); List(const List &lst);

// Member functions int getLength() const; elementType& operator [ ] (int position); List& operator = (const List &lst); bool insert(int position, elementType elt); bool remove(int position); bool retrieve(int position, elementType &elt);

protected: // Data members elementType entry[MAX_LIST_SIZE]; int length;

// Member function int Index(int position) const;};#define LIST_H#endif

Carrano - Chapter 3 CS 150 9

list.cpp//////////////////////////////////////////////////// list.cpp //// The class implementation for the List class. ////////////////////////////////////////////////////#include <iostream>#include <string>#include <cassert>#include "list.h"#include "phoneListing.h"

using namespace std;

// This default constructor sets up the List as one with no elements. //List::List(){ length = 0;}

// This copy constructor sets up the *this List //// as a duplicate of the parameterized List. //List::List(const List &lst){ length = lst.getLength(); for (int i = 1; i <= length; i++) entry[Index(i)] = lst.entry[Index(i)];}

// This accessor function retrieves the value of the length data member. //int List::getLength() const{ return length;}

Carrano - Chapter 3 CS 150 10

list.cpp (Continued)

// The subscript operator retrieves the element in the parameterized position //// of the entry data member. Note that the starting index for this operator //// is one, unlike the standard C++ starting index of zero. //elementType& List::operator [ ] (int position){ assert((position > 0) && (position <= length)); return entry[Index(position)];}

// The assignment operator gives the *this List duplicate //// values for each data member in the parameterized List. //List& List::operator = (const List &lst){ length = lst.getLength(); for (int i = 1; i <= length; i++) entry[Index(i)] = lst.entry[Index(i)]; return *this;}

Carrano - Chapter 3 CS 150 11

list.cpp (Continued)// This member function inserts the parameterized element into the *this List //// at the parameterized position (if there's room and the position is kosher). //bool List::insert(int position, elementType elt){ if ((position < 1) || (position > length + 1) || (length >= MAX_LIST_SIZE)) return false; else { length++; for (int i = length; i > position; i--) entry[Index(i)] = entry[Index(i-1)]; entry[Index(position)] = elt; return true; }}

// This member function removes the element at the parameterized //// position from the *this List (if the position is valid ). //bool List::remove(int position){ if ((position < 1) || (position > length)) return false; else { for (int i = position+1; i <= length; i++) entry[Index(i-1)] = entry[Index(i)]; length--; return true; }}

Carrano - Chapter 3 CS 150 12

list.cpp (Continued)

// This member function retrieves the element at the parameterized //// position from the *this List (if the position is kosher). //bool List::retrieve(int position, elementType &elt){ if ((position < 1) || (position > length)) return false; else { elt = entry[Index(position)]; return true; }}

// This member function converts the parameterized position into the //// corresponding index of the array that is the entry data member. //int List::Index(int position) const{ return position-1;}

Carrano - Chapter 3 CS 150 13

Now Let’s Test The List Class

//////////////////////////////////////////////////////////////// phoneDriver.cpp //// //// This program file tests the List class by loading a List //// variable and searching it with a user-supplied value. ////////////////////////////////////////////////////////////////

#include <iostream>#include <fstream>#include <string>#include "list.h"#include "phoneListing.h"

using namespace std;

List queryUserForDirectory();string queryUserForName();bool searchDirectory(List directory, string personsName, PhoneListing &listing);void outputListing(PhoneListing listing);void outputNoListing(string personsName);

Carrano - Chapter 3 CS 150 14

phoneDriver.cpp (Continued)

///////////////////////////////////////////////////////////////////////////////// The main function coordinates the user queries for the input file and the //// name being sought in the PhoneListing that is input. It also coordinates //// the output of the sought information (or its unavailability). /////////////////////////////////////////////////////////////////////////////////void main(){ List phoneBook; string soughtName; PhoneListing soughtPhoneListing;

phoneBook = queryUserForDirectory(); soughtName = queryUserForName(); if (searchDirectory(phoneBook, soughtName, soughtPhoneListing)) outputListing(soughtPhoneListing); else outputNoListing(soughtName); return;}

Carrano - Chapter 3 CS 150 15

phoneDriver.cpp (Continued)

///////////////////////////////////////////////////////////////////////// This function asks the user for the file name containing the List //// data, and then retrieves that data, using an end-of-file signal. /////////////////////////////////////////////////////////////////////////List queryUserForDirectory(){ ifstream directoryFile; char directoryFileName[50]; List directory; PhoneListing nextListing; int position = 1;

cout << "Enter the file name of the telephone directory data: "; cin >> directoryFileName; directoryFile.open(directoryFileName);

directoryFile >> nextListing; while (!directoryFile.eof()) { directory.insert(position, nextListing); position++; directoryFile >> nextListing; }

directoryFile.close(); return directory;}

Carrano - Chapter 3 CS 150 16

phoneDriver.cpp (Continued)/////////////////////////////////////////////////// This function asks the user for a string //// value that will be used to search the List. ///////////////////////////////////////////////////string queryUserForName(){ string name; cout << "Enter the name of the party whose number you want: "; cin >> name; return name;}

////////////////////////////////////////////////////////////////////////////////////// This function searches the parameterized List for a PhoneListing with the //// parameterized personsName. If it finds it, it sets the PhoneListing parameter //// and returns the value true; otherwise, it merely returns the value false. //////////////////////////////////////////////////////////////////////////////////////bool searchDirectory(List directory, string personsName, PhoneListing &listing){ PhoneListing dummyListing(personsName, ""); for (int i = 1; i <= directory.getLength(); i++) { directory.retrieve(i, listing); if (dummyListing == listing) return true; } return false;}

Carrano - Chapter 3 CS 150 17

phoneDriver.cpp (Continued)/////////////////////////////////////////////////////////////////////////////// This function outputs the PhoneListing found after a successful search. ///////////////////////////////////////////////////////////////////////////////void outputListing(PhoneListing listing){ cout << "Your requested listing - " << listing << endl << endl; return;}

//////////////////////////////////////////////////////////////////////////////////// This function outputs a message indicating that the search was unsuccessful. ////////////////////////////////////////////////////////////////////////////////////void outputNoListing(string personsName){ cout << "No listing with name: " << personsName << endl << endl; return;}

Carrano - Chapter 3 CS 150 18

phoneDriver.cpp (Continued)ACCT 2633AS 3180ANTH 2744ART 3071BIOL 3927BSED 2504CHEM 2042CE 2533CMIS 2504CS 2386CNST 2088CI 3082DANC 2773ESCI 3620ECON 2542EDUC 3277EDAD 3277ECE 2524ENG 2060ENVS 3311FIN 2638FL 3510GEOG 2090GRN 3454HED 3252

HIST 2414IE 3389IT 3277MGMT 2750MS 2638MKTG 3221MC 2230MATH 2382ME 3389MUS 3900NURS 3956PHIL 2250PHYS 2472POLS 3572PROD 2638PSYC 2202PAPA 3762SOCW 5758SOC 3713SPE 5423SPC 3090SPPA 3662THEA 2773WMST 5060

Contents of phoneData.txt

Sample

Output

Carrano - Chapter 3 CS 150 19

The Sorted List Abstract Data Type

We will now develop a class that implements a list that is always kept sorted, using whatever definition of sorting is associated with the type of element held in the list.

We’d like to be able to do the following:

•Insert a new element and have it automatically placed in its proper position in the list!

•Use a binary search to find elements in the list, and to locate where new elements should go in the list!

•Plus all of the other things we could do with our regular list!

Carrano - Chapter 3 CS 150 20

Defining Our SortedList Class

class SortedList{ public: // Class constructors SortedList(); SortedList(const SortedList &srtLst);

// Member functions int getLength() const; elementType& operator [ ] (int position); SortedList& operator = (const SortedList &srtLst); bool insert(elementType elt); bool remove(elementType elt); bool retrieve(elementType elt, int &position);

protected: // Data members elementType entry[MAX_LIST_SIZE]; int length;

// Member function int Index(int position) const; bool binarySearch(int firstPosition, int lastPosition, elementType soughtElt, int &position);};#define SORTED_LIST_H#endif

//////////////////////////////// sortedList.h //// The class definition for //// the SortedList class ////////////////////////////////#ifndef SORTED_LIST_H

#include <iostream>#include <string>#include "phoneListing.h"

using namespace std;

const int MAX_LIST_SIZE = 100;

typedef PhoneListing elementType;

Carrano - Chapter 3 CS 150 21

sortedList.cpp////////////////////////////////////////////////////////// sortedList.cpp //// The class implementation for the SortedList class. //////////////////////////////////////////////////////////#include <iostream>#include <string>#include <assert.h>#include "sortedList.h"#include "phoneListing.h"

using namespace std;

// This default constructor sets up the SortedList as one with no elements. //SortedList::SortedList(){ length = 0;}

// This copy constructor sets up the *this SortedList //// as a duplicate of the parameterized SortedList. //SortedList::SortedList(const SortedList &lst){ length = lst.getLength(); for (int i = 1; i <= length; i++) entry[Index(i)] = lst.entry[Index(i)];}

// This accessor function retrieves the value of the length data member. //int SortedList::getLength() const{ return length;}

Carrano - Chapter 3 CS 150 22

sortedList.cpp (Continued)

// The subscript operator retrieves the element in the parameterized position //// of the entry data member. Note that the starting index for this operator //// is one, unlike the standard C++ starting index of zero. //elementType& SortedList::operator [ ] (int position){ assert((position > 0) && (position <= length)); return entry[Index(position)];}

// The assignment operator gives the *this SortedList duplicate //// values for each data member in the parameterized List. //SortedList& SortedList::operator = (const SortedList &srtLst){ length = srtLst.getLength(); for (int i = 1; i <= length; i++) entry[Index(i)] = srtLst.entry[Index(i)]; return *this;}

Carrano - Chapter 3 CS 150 23

sortedList.cpp (Continued)// This member function inserts the parameterized element //// into the *this SortedList at the appropriate position //// (if there's room). //bool SortedList::insert(elementType elt){ int position; if (length >= MAX_LIST_SIZE) return false; else { retrieve(elt, position); length++; for (int i=length; i > position; i--) entry[Index(i)] = entry[Index(i-1)]; entry[Index(position)] = elt; return true; }}

// This member function removes the //// parameterized element from the *this // // SortedList (if it’s in the list). //bool SortedList::remove(elementType elt){ int position; if (!retrieve(elt, position)) return false; else { for (int i=position+1; i <= length; i++) entry[Index(i-1)] = entry[Index(i)]; length--; return true; }}

Carrano - Chapter 3 CS 150 24

sortedList.cpp (Continued)

// This member function retrieves the parameterized element //// from the *this SortedList (if it’s in the list), and sets //// the position parameter to its location in the list. //bool SortedList::retrieve(elementType elt, int &position){ return binarySearch(1, length, elt, position);}

// This member function converts the parameterized position into the //// corresponding index of the array that is the entry data member. //int SortedList::Index(int position) const{ return position-1;}

Carrano - Chapter 3 CS 150 25

sortedList.cpp (Continued)

// This member function performs a binary search on the SortedList for //// the soughtElt value. If it is successful, then parameter position //// will be assigned the location in the entry data member where the //// soughtElt was found; otherwise, it is assigned the location where //// it would be found if it were in the entry data member. //bool SortedList::binarySearch(int firstPosition, int lastPosition, elementType soughtElt, int &position){ int middlePosition = (firstPosition + lastPosition) / 2; if (lastPosition < firstPosition) { position = firstPosition; return false; } else if (entry[Index(middlePosition)] == soughtElt) { position = middlePosition; return true; } else if (entry[Index(middlePosition)] < soughtElt) return binarySearch(middlePosition+1, lastPosition, soughtElt, position); else return binarySearch(firstPosition, middlePosition-1, soughtElt, position);}

Carrano - Chapter 3 CS 150 26

Testing The SortedList Class

//////////////////////////////////////////////////////////////////////// phoneDriver2.cpp //// //// This program file tests the SortedList class by loading a //// SortedList variable and searching it with a user-supplied value. ////////////////////////////////////////////////////////////////////////

#include <iostream>#include <fstream>#include <string>#include "sortedList.h"#include "phoneListing.h"

using namespace std;

SortedList queryUserForDirectory();void outputDirectory(SortedList directory);string queryUserForName();bool searchDirectory(SortedList directory, string personsName, PhoneListing &listing);void outputListing(PhoneListing listing);void outputNoListing(string personsName);

Carrano - Chapter 3 CS 150 27

phoneDriver2.cpp (Continued)

///////////////////////////////////////////////////////////////////////////////// The main function coordinates the user queries for the input file and the //// name being sought in the PhoneListing that is input. It also coordinates //// the output of the sought information (or its unavailability). /////////////////////////////////////////////////////////////////////////////////void main(){ SortedList phoneBook; string soughtName; PhoneListing soughtPhoneListing;

phoneBook = queryUserForDirectory(); outputDirectory(phoneBook);

soughtName = queryUserForName(); if (searchDirectory(phoneBook, soughtName, soughtPhoneListing)) outputListing(soughtPhoneListing); else outputNoListing(soughtName); return;}

Carrano - Chapter 3 CS 150 28

phoneDriver2.cpp (Continued)

///////////////////////////////////////////////////////////////////////// This function asks the user for the file name containing the List //// data, and then retrieves that data, using an end-of-file signal. /////////////////////////////////////////////////////////////////////////SortedList queryUserForDirectory(){ ifstream directoryFile; char directoryFileName[50]; SortedList directory; PhoneListing nextListing;

cout << "Enter the file name of the telephone directory data: "; cin >> directoryFileName; directoryFile.open(directoryFileName);

directoryFile >> nextListing; while (!directoryFile.eof()) { directory.insert(nextListing); directoryFile >> nextListing; }

directoryFile.close(); return directory;}

Carrano - Chapter 3 CS 150 29

phoneDriver2.cpp (Continued)

////////////////////////////////////////////////////////////////// This function outputs the entire parameterized SortedList. //////////////////////////////////////////////////////////////////void outputDirectory(SortedList directory){ for (int i = 1; i <= directory.getLength(); i++) cout << directory[i] << endl; cout << endl; return;}

////////////////////////////////////////////////////// This function asks the user for a string value //// that will be used to search the SortedList. //////////////////////////////////////////////////////string queryUserForName(){ string name; cout << "Enter the name of the party whose number you want: "; cin >> name; return name;}

Carrano - Chapter 3 CS 150 30

phoneDriver2.cpp (Continued)

/////////////////////////////////////////////////////////////////////////////////////// This function searches the parameterized SortedList for a PhoneListing with the //// parameterized personsName. If it finds it, it sets the PhoneListing parameter //// and returns the value true; otherwise, it merely returns the value false. ///////////////////////////////////////////////////////////////////////////////////////bool searchDirectory(SortedList directory, string personsName, PhoneListing &listing){ int position; PhoneListing dummyListing(personsName, ""); if (directory.retrieve(dummyListing, position)) { listing = directory[position]; return true; } else return false;}

/////////////////////////////////////////////////////////////////////////////// This function outputs the PhoneListing found after a successful search. ///////////////////////////////////////////////////////////////////////////////void outputListing(PhoneListing listing){ cout << "Your requested listing - " << listing << endl << endl; return;}

Carrano - Chapter 3 CS 150 31

phoneDriver2.cpp (Continued)

/////////////////////////////////////////////////////////////////////////////// This function outputs the PhoneListing found after a successful search. ///////////////////////////////////////////////////////////////////////////////void outputListing(PhoneListing listing){ cout << "Your requested listing - " << listing << endl << endl; return;}

//////////////////////////////////////////////////////////////////////////////////// This function outputs a message indicating that the search was unsuccessful. ////////////////////////////////////////////////////////////////////////////////////void outputNoListing(string personsName){

cout << "No listing with name: " << personsName << endl << endl;return;

}

Carrano - Chapter 3 CS 150 32

phoneDriver2.cpp (Continued)