Containers and Iterators afe array class VectorInfo is an example o ainer” class: #include <iostream.h> #include <assert.h> typedef int Integer; typedef Integer * IntegerArray; typedef class VectorInfo * Vector; class VectorInfo { private: IntegerArray p; Integer size; public: VectorInfo(Integer n); ~VectorInfo(); Integer& element(Integer i); };
46
Embed
Containers and Iterators The safe array class VectorInfo is an example of a “container” class: #include typedef int Integer; typedef Integer * IntegerArray;
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Containers and Iterators
The safe array class VectorInfo is an example of a“container” class:
#include <iostream.h>#include <assert.h>
typedef int Integer;typedef Integer * IntegerArray;typedef class VectorInfo * Vector;
VectorInfo Class ImplementationVectorInfo::VectorInfo(Integer n){ assert ( n >= 1 ); size = n; p = new Integer[size]; assert (p != 0); for (Integer i = 0; i < n; i++) { // for demo purposes p[i] = i; // we fill array } // with index values}
VectorInfo::~VectorInfo() { delete [] p; }
Integer& VectorInfo::element(Integer i){ assert (i >= 0 && i <= size); return (p[i]);}
VectorInfo Class ApplicationFind the median value in a sorted Vector of n valuesby moving pointers from endpoints until they meet:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
front back0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
front back
backfront......
VectorInfo Class Application (cont'd)
Vector a = new VectorInfo(n);
Integer front_index = 0; Integer back_index = n;
Integer front = a->element(front_index++); Integer back = a->element(--back_index);
while ( front < back ) { cout << setw(5) << front << setw(5) << back << endl; front = a->element(front_index++); back = a->element(--back_index); } cout << "Middle value is " << front << endl;
Program Output for n = 15
6% a.out 0 14 1 13 2 12 3 11 4 10 5 9 6 8Middle value is 77%
Decoupling Index Handling from Loops
● The example has 6 places where Vector loop indexes have to be (confusingly!) managed:– front_index points directly to the next value– back_index does not– front_index is incremented after its use– back_index is decremented before its use
● Therefore, 6 opportunities for errors● Good OOP style prefers to keep index management
hidden from the implementor of the loop
Decoupling Index Handling: First Try
Instead of: Integer n = 15; Vector a = new VectorInfo(n); for (Integer i = 0; i < n; i++) cout << setw(4) << a->element(i); cout << endl;
Output: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
We would like: Integer n = 15; Vector a = new VectorInfo(n); for (Integer i = 0; i < n; i++) cout << setw(4) << a->next(); cout << endl;
Revised VectorInfo Class Definition
class VectorInfo {private: IntegerArray p; Integer size; Integer index; // Store index as part // of the objectpublic: VectorInfo(Integer n); ~VectorInfo(); Integer& element(Integer i); Integer& next(); // Let this method keep}; // track of the index
Revised VectorInfo Methods
VectorInfo::VectorInfo(Integer n){ assert ( n >= 1 ); size = n; p = new Integer[size]; assert (p != 0); for (Integer i = 0; i < n; i++) { p[i] = i; } index = 0; // Point index to beginning}
Trade-Offs● Advantage: index handling is performed by the class,
so coding is safer● Disadvantage 1: container class is beginning to not
have a single purpose● Disadvantage 2: Consider original example, in which
two indexes are needed:– front_index– back_index– However, as it stands, visitation over a Vector object is
restricted to one use, since there is one index– Like restricting a museum to one patron at a time
Possible Remedies
● Create multiple copies of the object– like creating multiple musems for multiple patrons
● Add multiple indexes to the class definition– How many? Can't know in advance– Makes container class even more complex
● Best solution: create an iterator class:– Sole purpose is to handle visitation of a container object– Multiple iterators can be created for one container– Like letting anyone in to the museum without knowing
how many
Iterator Classes
● Iterator classes handle the details of container visitation:– keep track of current index– implement hasNext() method– implement next() method
● Iterator class object must contain a pointer to the container it is iterating over
● When more than one iterative use of a container is needed, create more iterator objects (not more containers)
Integer& VectorIterInfo::previous() {// Note no circular if ( index == 0 ) // visitation. This throw "There is no previous."; // throw should be else // caught by the app return vector->element(--index); }
void VectorIterInfo::reset(Integer i) { index = i;}
Note that the next() method should also throw if there is no next element.
Original Example Again Integer n = 15; Vector a = new VectorInfo(n); VectorIter forward = new VectorIterInfo(a); forward->reset(0); VectorIter backward = new VectorIterInfo(a); backward->reset(n);
Integer front = forward->next(); Integer back = backward->previous();
while ( front < back ) { cout << setw(5) << front << setw(5) << back << endl; front = forward->next(); back = backward->previous(); } cout << "Middle value is " << front << endl;
This code should be enclosed in a try block with anappropriate catch clause.
Output
0 14 1 13 2 12 3 11 4 10 5 9 6 8Middle value is 7
Application: quickSort
10
716
4 918
-3 812
-3 4 7 8 910
12
16
18
Input:
Output:
Constraints: Perform the sort ``in place'' (no other memory is used)
quickSort Trace
10
716
4 9
comparisonelement
from to
18
-3 812
quickSort Trace (cont'd)
10
716
4 9
comparisonelement
from to
18
-3 812
18
16
12-3 7 8 4
109
partitioneverything less thancomparison element
everything greater thanor equal to comparison element
quickSort Trace (cont'd)
10
716
4 9
comparisonelement
from to
18
-3 812
18
16
12-3 7 8 4
109
partition
-3 7 8 4 9
partition16
12
18
partition
everything less thancomparison element
everything greater thanor equal to comparison element
quickSort Trace (cont'd)
10
716
4 9
comparisonelement
from to
18
-3 812
18
16
12-3 7 8 4
109
partition
-3 7 8 4 9
partition
4 7 8 9
16
12
18
partition
12
16
swappartition
everything less thancomparison element
everything greater thanor equal to comparison element
quickSort Trace (cont'd)
10
716
4 9
comparisonelement
from to
18
-3 812
18
16
12-3 7 8 4
109
partition
-3 7 8 4 9
partition
4 7 8 9
16
12
18
partition
12
16
swap
-3 4 7 8 910
12
16
18
partition
everything less thancomparison element
everything greater thanor equal to comparison element
if (compare >= front->getItem()) { swap(v->element(from), front->getItem()); return (front->getIndex()); } else { // in case pointers crossed in last iteration swap(v->element(from), v->element(front->getIndex() - 1) ); return (front->getIndex() - 1); }}
Analysis of quickSort
We will count the number of data movements thatquickSort does.
To do this we will use a recursion tree. We start withthe original vector as root:
0 N-1
Analysis of quickSort (cont'd)
0 N-1
After one call to partition:
Q: What is the maximum number of data movements necessary by this call to partition?
A: Movements per swap * Maximum swaps = 3 * N = O(N)
Analysis of quickSort (cont'd)
0 N-1
After two more calls to partition:
Q: What is the maximum number of data movements necessary for the second level?
A: movements per swap * maximum swaps = 3 * (2 * N/2) = 3 * N O(N)
Analysis of quickSort (cont'd)
● There are O(N) data movements per level of the recursion tree
● So the total number of data movements is:– O(N) * the number of levels
● How many levels are there?– Answer: the height of the recursion tree, which
depends upon the nature of the original data
Assuming Vector Values are Randomly Distributed0 N-1
Q: What is the height of this tree?
Assuming Vector Values are Randomly Distributed (cont'd)
N Levels 2 1 4 2 8 316 4 ... N log2N
Assuming Vector is Already Sorted or Nearly Sorted
0 N-1
. . .
.
.
.
Q: What is the height of this tree?A: N
Analysis of quickSort (Summary)
● The total number of data movements done by quickSort is:– O(Nlog(N)) if vector values are randomly distributed– O(N2) if vector is already sorted or nearly sorted
● In worst case, quickSort is no better than bubble sort, insertion sort, or selection sort
● In average case, quickSort is among the best● Analysis can proceed by counting other actions,