Data Structure - List
Data Structure - List
Hung-Ming Chen
NCTU EE
Fall 2023
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 1
Education, Inc. All rights reserved. 0-13-140909-3
Consider Every Day Lists
• Groceries to be purchased
• Job to-do list
• List of assignments for a course
• Dean's list
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 2
Education, Inc. All rights reserved. 0-13-140909-3
Properties of Lists
• Can have a single element
• Can have no elements
• There can be lists of lists
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 4
Education, Inc. All rights reserved. 0-13-140909-3
Designing a List Class
• Should contain at least the following function
members
– Constructor
– empty()
– insert()
– delete()
– display()
• Implementation involves
– Defining data members
– Defining function members from design phase
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 5
Education, Inc. All rights reserved. 0-13-140909-3
Array-Based Implementation
of Lists
• An array is a viable choice for storing list elements
– Elements are sequential
– It is a commonly available data type
– Algorithm development is easy
• Normally sequential orderings of list elements
match with array elements
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 6
Education, Inc. All rights reserved. 0-13-140909-3
Implementing Operations
• Constructor
– Static array allocated at compile time
• Empty
– Check if size == 0
• Traverse
– Use a loop from 0th element to size – 1
• Insert
– Shift elements to
right of insertion point Also adjust
size up or
• Delete down
– Shift elements back
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 7
Education, Inc. All rights reserved. 0-13-140909-3
List Class with Static Array
• Must deal with issue of declaration of
CAPACITY
• Use typedef mechanism
typedef Some_Specific_Type ElementType
ElementType array[CAPACITY];
• For specific implementation of our class we
simply fill in desired type for
Some_Specific_Type
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 8
Education, Inc. All rights reserved. 0-13-140909-3
List Class with Static Array
• Can put typedef declaration inside or
outside of class
– Inside: must specify List::ElementType
for reference to the type outside the class
– Outside: now able to use the template
mechanism (this will be our choice)
• Also specify the CAPACITY as a const
– Also choose to declare outside class (why not
inside?)
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 9
Education, Inc. All rights reserved. 0-13-140909-3
List Class Example
• Declaration file, Fig. 6.1A
– Note use of typedef mechanism outside the
class
– This example good for a list of int
• Definition, implementation Fig. 6.1B
– Note considerable steps required for insert()
and erase() functions
• Program to test the class, Fig 6.1C
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 10
Education, Inc. All rights reserved. 0-13-140909-3
Class List: static array
/*-- List.h ---------------------------------------------------------------
/***** insert and erase *****/
This header file defines the data type List for processing lists. void insert(ElementType item, int pos);
Basic operations are: /*----------------------------------------------------------------------
Constructor Insert a value into the list at a given position.
empty: Check if list is empty Precondition: item is the value to be inserted; there is room in
insert: Insert an item
erase: Remove an item the array (mySize < CAPACITY); and the position satisfies
display: Output the list 0 <= pos <= mySize.
<<, >> : input and output operators Postcondition: item has been inserted into the list at the position
-------------------------------------------------------------------------*/ determined by pos (provided there is room and pos is a legal
position).
#include <iostream>
-----------------------------------------------------------------------*/
#ifndef LIST void erase(int pos);
#define LIST /*----------------------------------------------------------------------
Remove a value from the list at a given position.
const int CAPACITY = 1024; Precondition: The list is not empty and the position satisfies
typedef int ElementType;
0 <= pos < mySize.
class List Postcondition: element at the position determined by pos has been
{ removed (provided pos is a legal position).
public: ----------------------------------------------------------------------*/
/******** Function Members ********/ /***** output *****/
/***** Class constructor *****/
List(); void display(ostream & out) const;
/*---------------------------------------------------------------------- /*----------------------------------------------------------------------
Construct a List object. Display a list.
Precondition: out is a reference parameter
Precondition: None Postcondition: The list represented by this List object has been
Postcondition: An empty List object has been constructed;
inserted into ostream out.
mySize is 0.
-----------------------------------------------------------------------*/ -----------------------------------------------------------------------*/
private:
/***** empty operation *****/ /******** Data Members ********/
bool empty() const; int mySize; // current size of list stored in myArray
/*----------------------------------------------------------------------
ElementType myArray[CAPACITY]; // array to store list elements
Check if a list is empty.
}; //--- end of List class
Precondition: None
Postcondition: true is returned if the list is empty, //------ Prototype of output operator
false if not. ostream & operator<< (ostream & out, const List & aList);
-----------------------------------------------------------------------*/
#endif
11
#include <cassert>
using namespace std; List Implementation if (pos < 0 || pos > mySize)
#include "List.h"
{
cerr << "*** Illegal location to insert -- " << pos
//--- Definition of class constructor << ". List unchanged. ***\n";
List::List() return;
: mySize(0) }
{ // First shift array elements right to make room for item
}
for(int i = mySize; i > pos; i--)
//--- Definition of empty() myArray[i] = myArray[i - 1];
bool List::empty() const
{ // Now insert item at position pos and increase list size
return mySize == 0;
myArray[pos] = item;
mySize++;
}
}
//--- Definition of display()
// Definition of erase()
void List::display(ostream & out) const void List::erase(int pos)
{ {
for (int i = 0; i < mySize; i++) if (mySize == 0)
out << myArray[i] << " "; {
} cerr << "*** List is empty ***\n";
return;
//--- Definition of output operator }
ostream & operator<< (ostream & out, const List & aList) if (pos < 0 || pos >= mySize)
{ {
aList.display(out);
cerr << "Illegal location to delete -- " << pos
<< ". List unchanged. ***\n";
return out;
return;
}
}
//--- Definition of insert() // Shift array elements left to close the gap
void List::insert(ElementType item, int pos) for(int i = pos; i < mySize; i++)
{ myArray[i] = myArray[i + 1];
if (mySize == CAPACITY)
{ // Decrease list size
cerr << "*** No space for list element -- terminating " mySize--;
"execution ***\n"; }
exit(1);
12
}
Test Driver
//--- Program to test List class.
cout << "\nTry to insert at position -1" << endl;
#include <iostream> intList.insert(0, -1);
using namespace std;
cout << "\nTry to insert at position 10" << endl;
intList.insert(0, 10);
#include "List.h"
// Test erase()
int index;
int main() cout << endl;
{ while (!intList.empty())
// Test the class constructor {
List intList; cout << "Give an index of a list element to remove: ";
cout << "Constructing intList\n"; cin >> index;
intList.erase(index);
// Test empty() and output of empty list
cout << intList << endl;
}
if (intList.empty())
cout << "List is empty" << endl;
cout << "Empty List: \n"
<< intList << endl; // Test output of empty list cout << "\nInserting " << CAPACITY<< " integers\n";
for (int i = 0; i < CAPACITY; i++)
// Test insert() intList.insert(i, i);
for (int i = 0; i < 9; i++) cout << "Attempting to insert one more integer:\n";
{ intList.insert(-1, 0);
cout << "Inserting " << i << " at position " << i/2 << endl;
intList.insert(i, i/2); // -- Insert i at position i/2 return 0;
//Test output
}
cout << intList << endl;
}
cout << "List empty? " << (intList.empty() ? "Yes" : "No") << endl;
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 13
Education, Inc. All rights reserved. 0-13-140909-3
Execution Trace for Test Program
14
List Class with Static Array -
Problems
• Stuck with "one size fits all"
– Could be wasting space
– Could run out of space
• Better to have instantiation of specific list
specifying what the capacity should be
• Thus we consider creating a List class with
dynamically-allocated array
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 15
Education, Inc. All rights reserved. 0-13-140909-3
Dynamic-Allocation for List Class
• Changes required in data members
– Eliminate const declaration for CAPACITY
– Add variable data member to store capacity specified by
client program
– Change array data member to a pointer
– Constructor requires considerable change
• Little or no changes required for
– empty()
– display()
– erase()
– insert()
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 16
Education, Inc. All rights reserved. 0-13-140909-3
Dynamic-Allocation for List Class
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 17
Education, Inc. All rights reserved. 0-13-140909-3
#include <iostream>
Class List: dynamic array /***** empty operation *****/
bool empty() const;
#ifndef LIST /*----------------------------------------------------------------------
#define LIST Check if a list is empty.
Precondition: None
typedef int ElementType; Postcondition: true is returned if the list is empty,
class List false if not.
{ -----------------------------------------------------------------------*/
public: /***** insert and erase *****/
/******** Function Members ********/ void insert(ElementType item, int pos);
/***** Class constructor *****/
List(int maxSize = 1024); /*----------------------------------------------------------------------
/*---------------------------------------------------------------------- Insert a value into the list at a given position.
Construct a List object. Precondition: item is the value to be inserted; there is room in
Precondition: maxSize is a positive integer with default value 1024. the array (mySize < CAPACITY); and the position satisfies
Postcondition: An empty List object is constructed; myCapacity == 0 <= pos <= mySize.
maxSize (default value 1024); myArrayPtr points to a run-time Postcondition: item has been inserted into the list at the position
array with myCapacity as its capacity; and mySize is 0. determined by pos (provided there is room and pos is a legal
-----------------------------------------------------------------------*/ position).
/***** Class destructor *****/ -----------------------------------------------------------------------*/
~List(); void erase(int pos);
/*---------------------------------------------------------------------- /*----------------------------------------------------------------------
Destroys a List object. Remove a value from the list at a given position.
Precondition: The life of a List object is over. Precondition: The list is not empty and the position satisfies
Postcondition: The memory dynamically allocated by the constructor 0 <= pos < mySize.
for the array pointed to by myArrayPtr has been returned to Postcondition: element at the position determined by pos has been
the heap. removed (provided pos is a legal position).
------------------------------------------------------------------*/
/***** Copy constructor *****/ ----------------------------------------------------------------------*/
List(const List & origList); /***** output *****/
/*---------------------------------------------------------------------- void display(ostream & out) const;
Construct a copy of a List object. /*----------------------------------------------------------------------
Precondition: A copy of origList is needed; origList is a const Display a list.
reference parameter. Precondition: The ostream out is open.
Postcondition: A copy of origList has been constructed. Postcondition: The list represented by this List object has been
-----------------------------------------------------------------------*/ inserted into out.
/***** Assignment operator *****/
List & operator=(const List & origList); -----------------------------------------------------------------------*/
/*---------------------------------------------------------------------- private:
Assign a copy of a List object to the current object. /******** Data Members ********/
Precondition: none int mySize; // current size of list stored in array
Postcondition: A copy of origList has been assigned to this int myCapacity; // capacity of array
object. A reference to this list is returned. ElementType * myArrayPtr; // pointer to dynamically-allocated array
-----------------------------------------------------------------------*/
}; //--- end of List class
//------ Prototype of output operator
ostream & operator<< (ostream & out, const List & aList);
18
#endif
#include <cassert>
#include <new>
Implementation //-- Allocate a new array if necessary
using namespace std;
if (myCapacity != origList.myCapacity)
#include "List.h" {
delete[] myArrayPtr;
//--- Definition of class constructor
myArrayPtr = new(nothrow) ElementType[myCapacity];
List::List(int maxSize)
: mySize(0), myCapacity(maxSize)
{ if (myArrayPtr == 0) // check if memory available
myArrayPtr = new(nothrow) ElementType[maxSize];
{
assert(myArrayPtr != 0);
} cerr << "*Inadequate memory to allocate stack ***\n";
exit(1);
//--- Definition of class destructor
}
List::~List()
{ }
delete [] myArrayPtr; //--- Copy origList's array into this new array
}
for(int i = 0; i < myCapacity; i++)
//--- Definition of the copy constructor myArrayPtr[i] = origList.myArrayPtr[i];
List::List(const List & origList) }
: mySize(origList.mySize), myCapacity(origList.myCapacity)
return *this;
{ }
//--- Get new array for copy
myArrayPtr = new(nothrow) ElementType[myCapacity];
//--- Definition of empty()
if (myArrayPtr != 0) // check if memory available bool List::empty() const
//--- Copy origList's array into this new array {
for(int i = 0; i < myCapacity; i++)
return mySize == 0;
myArrayPtr[i] = origList.myArrayPtr[i];
else }
{
cerr << "*Inadequate memory to allocate stack ***\n";
//--- Definition of display()
exit(1);
} void List::display(ostream & out) const
} {
for (int i = 0; i < mySize; i++)
//--- Definition of the assignment operator
List & List::operator=(const List & origList) out << myArrayPtr[i] << " ";
{ }
if (this != &origList) // check for list = list
{
mySize = origList.mySize; //--- Definition of output operator
ostream & operator<< (ostream & out, const List & aList)
{
aList.display(out);
return out; 19
}
Implementation (cont’d)
//--- Definition of insert()
//--- Definition of erase()
void List::insert(ElementType item, int pos)
void List::erase(int pos)
{
{
if (mySize == myCapacity)
if (mySize == 0)
{ {
cerr << "*** No space for list element -- terminating " cerr << "*** List is empty ***\n";
"execution ***\n"; return;
exit(1); }
} if (pos < 0 || pos >= mySize)
if (pos < 0 || pos > mySize) {
{ cerr << "Illegal location to delete -- " << pos
<< ". List unchanged. ***\n";
cerr << "*** Illegal location to insert -- " << pos
return;
<< ". List unchanged. ***\n";
}
return;
} // Shift array elements left to close the gap
for(int i = pos; i < mySize; i++)
// First shift array elements right to make room for item myArrayPtr[i] = myArrayPtr[i + 1];
20
Dynamic-Allocation for List Class
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 21
Education, Inc. All rights reserved. 0-13-140909-3
New Functions Needed
• Destructor
– When class object goes out of scope the pointer
to this memory is reclaimed automatically
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 24
Education, Inc. All rights reserved. 0-13-140909-3
Notes on Class Design
If a class allocates memory at run time using
the new, then it should provide …
• A destructor
• A copy constructor
• An assignment operator
• Three Amigos
• Note Fig. 6.3 which exercises constructors
and destructor
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 25
Education, Inc. All rights reserved. 0-13-140909-3
Calls to Constructors and Destructor
#include <iostream>
using namespace std; cout << "\n*** Next Statement: List list2 = list1;\n";
List list2 = list1;
#include "List.h" cout << "\n*** Next Statement: print(list2);\n";
print(list2);
void print (List aList) cout << "\n*** Next Statement: List list3;\n";
/*------------------------------------------------------------------------- List list3;
Function to print a list.
cout << "\n*** Next Statement: list3 = list2;\n";
list3 = list2;
Precondition: aList is a value parameter
cout << "\n*** Next Statement: print(list3);\n";
Postcondition: Contents of aList have been displayed
-------------------------------------------------------------------------*/
print(list3);
{
cout << aList << endl; cout << "\n*** Next Statement: return 0;\n";
} return 0;
}
int main()
{
int listLimit;
cout << "Enter maximum number of list elements: ";
cin >> listLimit;
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 27
Education, Inc. All rights reserved. 0-13-140909-3
Future Improvements to Our
List Class
• Problem 1: Array used has fixed capacity
Solution:
– If larger array needed during program execution
– Allocate, copy smaller array to the new one
• Problem 2: Class bound to one type at a
time
Solution:
– Create multiple List classes with differing
names
– Use class template
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 28
Education, Inc. All rights reserved. 0-13-140909-3
Recall Inefficiency of
Array-Implemented List
• insert() and erase() functions inefficient for
dynamic lists
– Those that change frequently
– Those with many insertions and deletions
So …
We look for an alternative implementation.
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 29
Education, Inc. All rights reserved. 0-13-140909-3
Linked List
For the array-based implementation:
1. First element is at location 0
2. Successor of item at location i is at location
i + 1
3. End is at location size – 1
Fix:
1. Remove requirement that list elements be stored
in consecutive location.
2. But then need a "link" that connects each element
to its successor
Linked Lists !!
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 30
Education, Inc. All rights reserved. 0-13-140909-3
Linked List
• Linked list nodes contain
– Data part – stores an element of the list
– Next part – stores link/pointer to next element
(when no next element, null value)
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 31
Education, Inc. All rights reserved. 0-13-140909-3
Linked Lists Operations
• Construction: first = null_value;
• Empty: first == null_value?
• Traverse
– Initialize a variable ptr to point to first node
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 32
Education, Inc. All rights reserved. 0-13-140909-3
Linked Lists Operations
• Traverse (ctd)
– set ptr = ptr->next, process ptr->data
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 33
Education, Inc. All rights reserved. 0-13-140909-3
Operations: Insertion
predptr
• Insertion newptr
20
– To insert 20 after 17
– Need address of item before point of insertion
– predptr points to the node containing 17
– Get a new node pointed to by newptr and store 20 in it
– Set the next pointer of this new node equal to the next
pointer in its predecessor, thus making it point to its
successor.
– Reset the next pointer of its predecessor to point to this
new node
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 34
Education, Inc. All rights reserved. 0-13-140909-3
Operations: Insertion
• Note: insertion also works at end of list
– pointer member of new node set to null
• Insertion at the beginning of the list
– predptr must be set to first
– pointer member of newptr set to that value
– first set to value of newptr
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 35
Education, Inc. All rights reserved. 0-13-140909-3
Operations: Deletion
predptr ptr
To free
• Delete node containing 22 from list. space
– Suppose ptr points to the node to be deleted
– predptr points to its predecessor (the 17)
• Do a bypass operation:
– Set the next pointer in the predecessor to
point to the successor of the node to be deleted
– Deallocate the node being deleted.
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 36
Education, Inc. All rights reserved. 0-13-140909-3
Linked Lists - Advantages
• Access any item as long as external link
to first item maintained
• Insert new item without shifting
• Delete existing item without shifting
• Can expand/contract as necessary
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 37
Education, Inc. All rights reserved. 0-13-140909-3
Linked Lists - Disadvantages
• Overhead of links:
– used only internally, pure overhead
• If dynamic, must provide
– destructor
– copy constructor
• No longer have direct access to each element of
the list
– Many sorting algorithms need direct access
– Binary search needs direct access
• Access of nth item now less efficient
– must go through first element, and then second, and
then third, etc.
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 38
Education, Inc. All rights reserved. 0-13-140909-3
Linked Lists - Disadvantages
• List-processing algorithms that require fast access to each
element cannot be done as efficiently with linked lists.
• Consider adding an element at the end of the list
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 41
Education, Inc. All rights reserved. 0-13-140909-3
Working with Nodes
• Note data members class Node
{ public:
are public DataType data;
Node * next; };
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 43
Education, Inc. All rights reserved. 0-13-140909-3
Data Members for Linked-List
Implementation
– set mySize to 0
• Destructor
– Nodes are dynamically allocated by new
– Default destructor will not specify the delete
• All the nodes from that point on would be
"marooned memory"
– A destructor must be explicitly implemented to
do the delete
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 45
Education, Inc. All rights reserved. 0-13-140909-3
Function Members for Linked-List
Implementation
Shallow Copy
int next;
};
const int NULL_VALUE = -1;
// Storage Pool
const int NUMNODES = 2048;
NodeType node [NUMNODES];
int free;
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 47
Education, Inc. All rights reserved. 0-13-140909-3
Array-Based Implementation of
Linked Lists
• Given a list with names
• Implementation looks
like this
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 48
Education, Inc. All rights reserved. 0-13-140909-3
Array-Based Implementation of
Linked Lists
• To traverse
ptr = first;
while (ptr != NULL_VALUE)
{
// process data at node[ptr].data
ptr = node[ptr].next;
}
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 49
Education, Inc. All rights reserved. 0-13-140909-3
Organizing Storage Pool
• In the array
– Some locations are storing nodes of the list
– Others are free nodes, available for new data
• Could initially link all nodes as free
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 50
Education, Inc. All rights reserved. 0-13-140909-3
Organizing Storage Pool
• Then use nodes as required for adds and
inserts
– Variable free points to beginning of linked nodes
of storage pool
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 51
Education, Inc. All rights reserved. 0-13-140909-3
Organizing Storage Pool
• Links to actual list and storage pool
maintained as new data nodes are added
and deleted
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 52
Education, Inc. All rights reserved. 0-13-140909-3
A Peek in list’s Memory
Management
• To reduce the inefficiency of using the
system’s heap manager for large numbers of
allocations and deallocations, it does its own
management of a free list of available nodes
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 54
Education, Inc. All rights reserved. 0-13-140909-3
“Programming Proverbs” -1
Don’t take a long walk off a short linked list.
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 55
Education, Inc. All rights reserved. 0-13-140909-3
“Programming Proverbs” -1
Don’t take a long walk off a short linked list.
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 56
Education, Inc. All rights reserved. 0-13-140909-3
“Programming Proverbs” -1
Don’t take a long walk off a short linked list.
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 57
Education, Inc. All rights reserved. 0-13-140909-3
“Programming Proverbs” -2
You can’t get water from an empty well.
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 58
Education, Inc. All rights reserved. 0-13-140909-3
“Programming Proverbs” -3
Don’t burn bridges before you cross them.
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson 59
Education, Inc. All rights reserved. 0-13-140909-3