Professional Documents
Culture Documents
3 LinkedLists
3 LinkedLists
1
WHAT ARE SOME OF THE
IMPORTANT PROBLEMS?
• THE most important and most frequent task a
computer does ALL THE TIME is
– Searching
• The next most important thing is probably
– Sorting
2
SEARCHING
• Simple version
– Given a set of objects S, and a query object x, is x in
S?
3
SEARCHING
• Simple version
– Given a set of objects S, and a query object x, is x in
S?
• Complex version
– Given a set of objects S, and a partial information
about an object X, is there a set element which is
similar to X in some sense?
4
CONSIDERATIONS
5
CONSIDERATIONS
6
CONSIDERATIONS
7
CONSIDERATIONS
8
CONSIDERATIONS
9
CONSIDERATIONS
10
CONSIDERATIONS
11
CONSIDERATIONS
12
CONSIDERATIONS
13
CONSIDERATIONS
14
HOW TO COMPARE?
• Equality
– Is X in S?
15
HOW TO COMPARE?
• Equality
– Is X in S?
• Functional relationship
– Is there an element Y such that F(Y) = X?
16
HOW TO COMPARE?
• Equality
– Is X in S?
• Functional relationship
– Is there an element Y such that F(Y) = X?
• Is there a student (Y) with LastName(Y)=“Öztürk”?
• List all students (Ys) with GPA(Y) = 3.00
17
HOW TO COMPARE?
• Inequality
– Is there an element larger than X?
– Is there an element NOT equal to X?
– Is there an element between X and Y?
18
HOW TO COMPARE?
• Closeness
– What is/are the element(s) “closest” to X?
– What elements are at most “distance” y away from
X?
19
HOW TO COMPARE?
• Closeness
– What is/are the element(s) “closest” to X?
• What are the “correct” versions of the misspelled Turkish
words
– iktapalrdaik
– evdaki
– Çekoslovakyalıleştırabliemediklerimizdenmişsinizcsine
20
HOW TO COMPARE?
• Closeness
– What is/are the element(s) “closest” to X?
• What are the “correct” versions of the misspelled words
– iktapalrdaik (kitaplardaki)
– evdaki (avdaki, evdeki)
– Çekoslovakyalılaştırabilemediklerimizdenmişsinizcesine
21
HOW TO COMPARE?
• Closeness
– What is/are the element(s) “closest” to X?
• What are the “correct” versions of the misspelled words
– iktapalrdaik (kitaplardaki)
– evdaki (avdaki, evdeki)
– Çekoslovakyalılaştırabilemediklerimizdenmişsinizcesine
– What is the “correct” Turkish sentence closest in
meaning to “Ben var şiş kebap yemek?”
22
HOW TO COMPARE?
• Closeness
– What is/are the element(s) “closest” to X?
• What are the “correct” versions of the misspelled words
– iktapalrdaik (kitaplardaki)
– evdaki (avdaki, evdeki)
– Çekoslovakyalılaştırabilemediklerimizdenmişsinizcesine
– What is the Turkish sentence closest in meaning to
“Ben var şiş kebap yemek”?
• Ben şiş kebap yedim
23
HOW TO COMPARE?
• Closeness
– Find 6 letter words whose first letter is a and whose
last letter is m?
24
WHAT IF S IS INFINITE?
25
WHAT IF S IS INFINITE?
26
WHAT IF COMPARISON IS NOT
EASY?
• Find 6 letter words whose first letter is a and
whose last letter is m?
– alaşım, atılım, aküzüm, alaçam, anonim, arıtım,...
27
WHAT IF COMPARISON IS NOT
EASY?
• Whose fingerprint is this?
28
WHAT IF COMPARISON IS NOT
EASY?
• Whose fingerprint is
this?
29
WHAT IF COMPARISON IS NOT
EASY?
• Whose fingerprint is
this?
30
WHAT IF COMPARISON IS NOT
EASY?
• Should I run away?
31
WHAT IF COMPARISON IS NOT
EASY?
• Should I run away?
32
LESSON
34
ABSTRACT DATA TYPES
35
ABSTRACT DATA TYPES
38
ABSTRACT DATA TYPES
39
ABSTRACT DATA TYPES
41
REPRESENTATION VS TYPE
42
REPRESENTATION VS TYPE
Type
43
REPRESENTATION VS TYPE
Type
44
REPRESENTATION VS TYPE
45
REPRESENTATION VS TYPE
46
REPRESENTATION VS TYPE
Type
47
REPRESENTATION VS TYPE
48
REPRESENTATION VS TYPE
49
REPRESENTATION VS TYPE
• A given ADT may be based on different
representations.
• Sets: intersect, union, size, membership...
• Representations (which themselves can be
ADTs)
– Bit Vectors
– Hash Tables
– Linked Lists
– Trees
– ....
50
ADTs VS OBJECTS
51
ADTS VS OBJECTS
• But ...
52
ADTS VS OBJECTS
53
ADTS VS OBJECTS
• Objects (as in C++) are convenient mechanisms
for implementing ADTs in programming
languages.
55
LINKED LISTS
56
LINKED LISTS
57
LINKED LISTS
58
LINKED LISTS
• A linked list is an ordered sequence of data items:
A1, A2, A3, .... , AN
– An empty list has no elements
– For any list except the empty list
• A i+1 follows or succeeds Ai (i < N )
• A i-1 precedes Ai (i > 1)
– Ai is at position i
– Data items Ai can be of any type
– In general, the (maximum) number of elements, N, is
not known in advance!
59
DIGRESSION - POINTERS
60
POINTERS
• char * c;
– c is a pointer pointing to a single character;
61
POINTERS
• char * c;
– c is a pointer pointing to a single character;
• int * i;
– i is a pointer pointing to an integer.
– You can also read this as “the type of “*i” is an
integer.
– * is the “content-of” operator.
62
POINTERS
• int j, *i, k;
• k=5;
• i= &k; //i gets the address of k;
• *i = 6 ; // k is now 6
• j= *i ; // j now is also 6
63
POINTERS
• char c = ‘a’ ; 0
c 4
12
16
20
24
64
POINTERS
• char c = ‘a’ ; 0
c 4 a
12
16
20
24
65
POINTERS
• char c = ‘a’ ; 0
• int i;
c 4 a
i 8
12
16
20
24
66
POINTERS
• char c = ‘a’ ; 0
• int i;
c 4 a
• char *p = & c;
i 8
p 12 0 0 0 4
16
20
24
67
POINTERS
• char c = ‘a’ ; 0
• int i; c 4 a
• char *p = & c;
i 8
• int *j ;
p 12 0 0 0 4
j 16
20
24
68
POINTERS
• char c = ‘a’ ; 0
• int i; c 4 a
• char *p = & c;
i 8
• int *j ;
p 12 0 0 0 4
• j= &i; j 16 0 0 0 8
20
24
69
POINTERS
• char c = ‘a’ ; 0
• int i; c 4 a
• char *p = & c;
i 8 0 0 0 67
• int *j ;
p 12 0 0 0 4
• j= &i; j 16 0 0 0 8
• *j = 67;
20
24
70
POINTERS
• char c = ‘a’ ; 0
• int i; c 4 a b
• char *p = & c;
i 8 0 0 0 67
• int *j ;
p 12 0 0 0 4
• j= &i; j 16 0 0 0 8
• *j = 67;
20
• *(p+1) = ‘b’;
24
71
POINTER ARITHMETIC
72
POINTERS
• char C = ‘a’ ; 0
• int i; c 4 a b
• char *p = & c;
i 8 0 0 0 67
• int *j ;
p 12 0 0 0 4
• j= &i; j 16 0 0 0 8
• *j = 67;
20
• *(p+1) = ‘b’;
24
73
POINTER ARITHMETIC
74
POINTER ARITHMETIC
75
POINTER ARITHMETIC
76
ARRAYS AND POINTERS
77
ARRAYS AND POINTERS
78
STRINGS
Courtesy Berrin Yanıkoğlu
79
ARRAYS AND POINTERS
80
ARRAYS AND POINTERS
81
POINTERS
82
POINTERS
Date today;
Date *p_date; //preferred naming - starts with p
83
POINTERS ARE POWERFUL, IF YOU
KNOW WHAT YOU ARE DOING
• DELETE any object when it is no longer needed
1. Date *d1 = new Date(); // allocate
2. delete d1; // delete when not needed
• AVOID memory leaks!!!
1. Date *d1 = new Date(); d1
A1 A2 A3
First Element
(Head) Pointers to the next element in the list
... AN—1 AN
Last Element
Null pointer
85
LINKED LISTS
Deleting an element
A1 A2 A3 A4 A5
A1 A2 A3 A4 A5
86
LINKED LISTS
Deleting an element
A1 A2 A3 A4 A5
A1 A2 A4 A5
A3
87
LINKED LISTS
Deleting an element
A1 A2 A3 A4 A5
A1 A2 A4 A5
A3
88
LINKED LISTS
Inserting an element
A1 A2 A3 A4 A5
Insertion point A6
89
LINKED LISTS
Inserting an element
A1 A2 A3 A4 A5
A6
90
LINKED LISTS
Inserting an element
A1 A2 A3 A4 A5
A6
91
LINKED LISTS
Inserting an element
A1 A2 A6 A3 A4
A5
92
LINKED LISTS
A1 A2 A6 A3
A4
The methods are a bit easier to write.
A5
93
LINKED LISTS
LISTNODE CLASS
A1
template <class Object>
class List; // Incomplete declaration.
Object element;
ListNode *next;
94
LINKED LISTS
LISTNODE CLASS
A1
template <class Object>
class List; // Incomplete declaration.
95
LINKED LISTS
LISTNODE CLASS
friend class List<Object>; // Other objects that can access the private fields
friend class ListItr<Object>;
};
96
friends of a class
• friend class List<Object>;
• friend class ListItr<Object>;
97
friends of a class
• But this is a one way access.
98
LINKED LISTS
LISTNODE CLASS
Object element;
ListNode *next;
99
CLASS TEMPLATES
template <class Object>
class ListNode
{
ListNode( const Object & theElement = Object( ),
ListNode * n = NULL )
: element( theElement ), next( n ) { }
Object element;
ListNode *next;
100
LISTNODE STORING A DATE
class DateListNode
{
...
Date element;
DateListNode *next;
...
};
101
LISTNODE STORING A
RECTANGLE
class RectangleListNode
{
...
Rectangle element;
RectangleListNode *next;
...
};
102
LISTNODE STORING A CIRCLE
class CircleListNode
{
...
Circle element;
CircleListNode *next;
...
};
103
CLASS TEMPLATES
template <class Object> A template parameter is a
class ListNode special kind of parameter
{ that can be used to pass a
ListNode( const Object & theElement = Object( ), ListNode * n = NULL ) type as argument: just like
: element( theElement ), next( n ) { } regular function
parameters can be used to
Object element; pass values to a function
ListNode *next;
It represents a type that
friend class List<Object>; has not yet been specified
friend class ListItr<Object>;
};
class ListNode
{
ListNode( const Date & theElement = Date( ), ListNode * n = NULL )
: element( theElement ), next( n ) { }
Date element;
ListNode *next;
104
CLASS TEMPLATES
template <class Object>
class ListNode
{
ListNode( const Object & theElement = Object( ), ListNode * n = NULL )
: element( theElement ), next( n ) { }
Object element;
ListNode *next;
class ListNode
{
ListNode( const Rectangle & theElement = Rectangle( ), ListNode * n = NULL )
: element( theElement ), next( n ) { }
Rectangle element;
ListNode *next;
105
CLASS TEMPLATES
template <class Object>
class ListNode
{
ListNode( const Object & theElement = Object( ), ListNode * n = NULL )
: element( theElement ), next( n ) { }
Object element;
ListNode *next;
class ListNode
{
ListNode( const Circle & theElement = Circle( ), ListNode * n = NULL )
: element( theElement ), next( n ) { }
Circle element;
ListNode *next;
106
LIST ITERATOR
The list iterator is an object that keeps
track of list positions
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
private:
ListNode<Object> *current; // Current position
private:
ListNode<Object> *current; // Current position
private:
ListNode<Object> *current; // Current position
private:
ListNode<Object> *current; // Current position
private:
ListNode<Object> *current; // Current position
115
EXCEPTIONS
• Exceptions are anomalies that occur during
the normal flow of a program and prevent it
from continuing.
• These anomalies--user, logic, or system
errors--can be detected by a function.
116
EXCEPTIONS
• Exceptions are anomalies that occur during
the normal flow of a program and prevent it
from continuing.
• These anomalies--user, logic, or system
errors--can be detected by a function.
• If the detecting function cannot deal with
the anomaly, it "throws" an exception.
117
EXCEPTIONS
• Exceptions are anomalies that occur during
the normal flow of a program and prevent it
from continuing.
• These anomalies--user, logic, or system
errors--can be detected by a function.
• If the detecting function cannot deal with
the anomaly, it "throws" an exception.
• A function that "handles" that kind of
exception “catches” it.
118
EXCEPTIONS
120
EXCEPTIONS
121
EXCEPTIONS
122
EXCEPTIONS
123
EXCEPTIONS
124
EXAMPLE
#include <iostream.h>;
int main () {
try
{
char * mystring;
mystring = new char [10];
if (mystring == NULL) throw "Allocation failure";
for (int n=0; n<=100; n++)
{
if (n> 9) throw n;
mystring[n]='z';
}
}
catch (int i)
{
cout << "Exception: ";
cout << "index " << i << " is out of range" <<endl;
exit (-1)
}
catch (char * str)
{
cout << "Exception: " << str << endl;
exit(-1)
} 125
}
EXAMPLE
#include <iostream.h>;
Compiler knows which handler
int main () {
try
to invoke looking at the types.
{
char * mystring;
mystring = new char [10];
if (mystring == NULL) throw "Allocation failure";
for (int n=0; n<=100; n++)
{
if (n> 9) throw n;
mystring[n]='z';
}
}
catch (int i)
{
cout << "Exception: ";
cout << "index " << i << " is out of range" <<endl;
exit (-1)
}
catch (char * str)
{
cout << "Exception: " << str << endl;
exit(-1)
} 126
}
EXAMPLE
#include <iostream.h>;
Exception: index 10 is out of range
int main () {
try
{
char * mystring;
mystring = new char [10];
if (mystring == NULL) throw "Allocation failure";
for (int n=0; n<=100; n++)
{
if (n> 9) throw n;
mystring[n]='z';
}
}
catch (int i)
{
cout << "Exception: ";
cout << "index " << i << " is out of range" <<endl;
exit (-1)
}
catch (char * str)
{
cout << "Exception: " << str << endl;
exit(-1)
} 127
}
EXAMPLE
128
EXAMPLE
class BadIterator {
public:
BadIterator() {}
};
130
(Back to) LISTS
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 );
private:
ListNode<Object> *header;
}; 131
(Back to) LISTS
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 );
private:
ListNode<Object> *header;
}; 132
LISTS
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 );
private:
ListNode<Object> *header;
}; 133
LISTS
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 );
private:
ListNode<Object> *header;
}; 134
LISTS
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 );
private:
ListNode<Object> *header;
}; 135
LISTS
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 );
private:
ListNode<Object> *header;
}; 136
LISTS
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 );
private:
ListNode<Object> *header;
}; 137
LISTS
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 );
private:
ListNode<Object> *header;
}; 138
LISTS
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 );
private:
ListNode<Object> *header;
}; 139
CONSTRUCTOR
/**
* Construct the list.
*/
template <class Object>
List<Object>::List( )
{
header = new ListNode<Object>;
}
140
isEmpty
/**
* Test if the list is logically empty.
* Return true if empty, false, otherwise.
*/
template <class Object>
bool List<Object>::isEmpty( ) const
{ // see if the header point to NULL
return header–>next == NULL;
}
141
insert
/**
* 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 );
} p.current insert here
A1 A2 A3 A4
X
142
find
/**
* 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
{
ListNode<Object> *itr = header->next;
143
find
/**
* 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
{
ListNode<Object> *itr = header->next; // Initialize
144
find
/**
* 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
{
ListNode<Object> *itr = header->next; // Initialize
145
find
/**
* 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
{
ListNode<Object> *itr = header->next; // Initialize
/**
* 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
{
ListNode<Object> *itr = header->next; // Initialize
147
findPrevious
/**
* Return iterator prior to the first node containing an item x. */
148
findPrevious
/**
* Return iterator prior to the first node containing an item x. */
149
remove
/**
* Remove the first occurrence of an item x.
*/
template <class Object>
void List<Object>::remove( const Object & x )
{
ListItr<Object> p = findPrevious( x );
150
remove
/**
* Remove the first occurrence of an item x.
*/
template <class Object>
void List<Object>::remove( const Object & x )
{
ListItr<Object> p = findPrevious( x ); // Locate previous of x, if any
A1 x A3 A4
151
remove
/**
* Remove the first occurrence of an item x.
*/
template <class Object>
void List<Object>::remove( const Object & x )
{
ListItr<Object> p = findPrevious( x ); // Locate previous of x, if any
A1 x A3 A4
152
remove
if( p.current->next != NULL ) // not null if x is in the list!
{
ListNode<Object> *oldNode = p.current->next;
p.current->next = p.current->next->next; // Bypass deleted node
delete oldNode;
}
}
A1 x A3 A4
oldNode
153
remove
if( p.current->next != NULL ) // not null if x is in the list!
{
ListNode<Object> *oldNode = p.current->next;
p.current->next = p.current->next->next; // Bypass deleted node
delete oldNode;
}
}
A1 x A3 A4
oldNode
154
remove
if( p.current->next != NULL ) // not null if x is in the list!
{
ListNode<Object> *oldNode = p.current->next;
p.current->next = p.current->next->next; // Bypass deleted node
delete oldNode;
}
}
A1 A3 A4
155
zeroth
/**
* Return an iterator representing the header node.
*/
template <class Object>
ListItr<Object> List<Object>::zeroth( ) const
{
return ListItr<Object>( header );
}
Note that we are using the constructor of ListItr (since we declared List to be a
friend of ListItr)
156
first
/**
* 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 );
}
157
makeEmpty
/**
* Make the list logically empty.
*/
template <class Object>
void List<Object>::makeEmpty( )
{
while( !isEmpty( ) )
remove( first( ).retrieve( ) );
}
158
Deep Copy
/**
* Deep copy of linked lists.
*/
template <class Object>
const List<Object> & List<Object>::operator=( const List<Object> & rhs )
{
if( this != &rhs )
{
makeEmpty( );
159
Shallow Copy vs Deep Copy
Shallow Copy
X A X is a pointer to an object
Y Y is a pointer
Y = X is a shallow copy
160
Shallow Copy vs Deep Copy
Deep Copy
X A X is a pointer to an object
Y Y is a pointer
161
Shallow Copy
List<Object> A;
List<Object> B;
B=A; // gets automatically converted to B.operator=(A)
A.header
A1 A2 A3 A4
B.header
162
(Back to) LISTS
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 );
private:
ListNode<Object> *header;
}; 163
Deep Copy
/**
* Deep copy of linked lists.
*/
template <class Object>
const List<Object> & List<Object>::operator=( const List<Object> & rhs )
{
if( this != &rhs )
{
makeEmpty( );
164
Deep Copy
/**
* Deep copy of linked lists.
*/
template <class Object>
const List<Object> & List<Object>::operator=( const List<Object> & rhs )
{
if( this != &rhs ) // Make sure objects are different
{
makeEmpty( );
165
Deep Copy
/**
* Deep copy of linked lists.
*/
template <class Object>
const List<Object> & List<Object>::operator=( const List<Object> & rhs )
{
if( this != &rhs ) // Make sure objects are different
{
makeEmpty( ); // Clean up this object
166
Deep Copy
/**
* Deep copy of linked lists.
*/
template <class Object>
const List<Object> & List<Object>::operator=( const List<Object> & rhs )
{
if( this != &rhs ) // Make sure objects are different
{
makeEmpty( ); // Clean up this object
167
Deep Copy
/**
* Deep copy of linked lists.
*/
template <class Object>
const List<Object> & List<Object>::operator=( const List<Object> & rhs )
{
if( this != &rhs ) // Make sure objects are different
{
makeEmpty( ); // Clean up this object
168
Deep Copy
List<Object> A;
List<Object> B;
B=A; // gets automatically converted to B.operator=(A)
A.header
A1 A2 A3 A4
A1 A2 A3 A4
169
B.header
COPY CONSTRUCTOR
/**
* Copy constructor.
*/
template <class Object>
List<Object>::List( const List<Object> & rhs )
{
header = new ListNode<Object>;
*this = rhs; // Deep Copy
}
170
COPY CONSTRUCTOR
/**
* Copy constructor.
*/
template <class Object>
List<Object>::List( const List<Object> & rhs )
{
header = new ListNode<Object>;
*this = rhs; // Deep Copy
}
171
COPY CONSTRUCTOR
172
Shallow Copy
void foo(List<Object> B){ … }
List<Object> A;
A.header
A1 A2 A3 A4
173
Deep Copy
void foo(List<Object> B){ … }
List<Object> A;
A.header
A1 A2 A3 A4
A1 A2 A3 A4
175
USING LISTS
// Simpleprint function
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( ) << " ";
}
176
USING LISTS
// Simpleprint function
template <class Object>
void printList( const List<Object> & theList )
{
if( theList.isEmpty( ) ) // if the list empty
cout << "Empty list" << endl;
else
{
ListItr<Object> itr = theList.first( );
for( ; !itr.isPastEnd( ); itr.advance( ) )
cout << itr.retrieve( ) << " ";
}
177
USING LISTS
// Simpleprint function
template <class Object>
void printList( const List<Object> & theList )
{
if( theList.isEmpty( ) ) // if the list empty
cout << "Empty list" << endl;
else
{ // print each element one by one
ListItr<Object> itr = theList.first( );
for( ; !itr.isPastEnd( ); itr.advance( ) )
cout << itr.retrieve( ) << " ";
}
178
USING LISTS
int main( )
{
List<int> theList;
ListItr<int> theItr = theList.zeroth( );
int i;
printList( theList );
179
USING LISTS
for( i = 0; i < 10; i += 2 )
theList.remove( i );
printList( theList );
List<int> list2;
list2 = theList;
printList( list2 );
return 0;
}
180
USING LISTS
Empty List
0
01
012
0123
01234
012345
0123456
01234567
012345678
0123456789
Find fails for 0
Find succeeds for 1
Find fails for 2
Find succeeds for 3
Find fails for 4
Find succeeds for 5
Find fails for 6
Find succeeds for 7
Find fails for 8
Find succeeds for 9
13579
13579
181
Reading List
Paul J.Deitel and Harvey M.Deitel, “ C++ for Programmers:
Deitel® Developer Series” , Prentice Hall, 2009 (available as
an e-book at Information Center).
Section 10.2. const (Constant) Objects and const Member
Functions
Section 10.4. friend Functions and friend Classes
Section 10.5. Using the this Pointer
Chapter 11. Operator Overloading; String and Array Objects
Chapter 14. Templates
Chapter 16. Exception Handling
182
COMPLEXITY OF LIST OPERATIONS
183
COMPLEXITY OF LIST OPERATIONS
184
COMPLEXITY OF LIST OPERATIONS
185
COMPLEXITY OF LIST OPERATIONS
186
COMPLEXITY OF LIST OPERATIONS
187
COMPLEXITY OF LIST OPERATIONS
188
FIND: AVERAGE CASE ANALYSIS
i # of nodes visited
1 1
2 2
3 3
... ...
N N
189
VARIATIONS ON LISTS
A1 A2 A3 A4
190
VARIATIONS ON LISTS
191
VARIATIONS ON LISTS
Data Field
192
DOUBLY LINKED LIST
193
DOUBLY LINKED LIST
194
DOUBLY LINKED LIST
196
USING LISTS:POLYNOMIALS
197
POLYNOMIALS
198
POLYNOMIALS
class Term {
private:
// methods for constructing and destroying go here
int coefficient;
int exponent;
199
POLYNOMIALS
class Polynomial
{
// we assume that the list nodes are ordered by
// decreasing exponent
public:
Polynomial( );
void insertTermAtFront(int coef, int exp);
void zeroPolynomial( );
Polynomial operator+( const Polynomial & rhs ) const;
Polynomial operator*( const Polynomial & rhs ) const;
void print( ostream & out ) const;
private:
List<Term> terms;
};
200
POLYNOMIAL ADDITION
201
POLYNOMIALS
class Polynomial
{
// we assume that the list nodes are ordered by
// decreasing exponent
public:
Polynomial( );
void insertTermAtFront(int coef, int exp);
void zeroPolynomial( );
Polynomial operator+( const Polynomial & rhs ) const;
Polynomial operator*( const Polynomial & rhs ) const;
void print( ostream & out ) const;
private:
List<Literal> terms;
};
202
POLYNOMIAL ADDITION
203
POLYNOMIAL ADDITION
204
POLYNOMIAL ADDITION
205
POLYNOMIAL ADDITION
206
POLYNOMIAL ADDITION
207
POLYNOMIAL ADDITION
208
POLYNOMIAL ADDITION
209
POLYNOMIAL ADDITION
210
POLYNOMIAL ADDITION
211
POLYNOMIAL ADDITION
212
POLYNOMIAL ADDITION
213
POLYNOMIAL ADDITION
• We are done
214
POLYNOMIAL ADDITION
Polynomial& Polynomial::operator+(const Polynomial & Second) const
{
//initialize list iterators
ListItr<Term> X = terms.first();
ListItr<Term> Y = Second.terms.first();
Polynomial output;
215
POLYNOMIAL ADDITION
else if (X.retrieve().Exponent < Y.retrieve().Exponent) {
output.insertTermAtFront(Y.retrieve().Coefficient,
Y.retrieve().Exponent);
Y.advance();
}
else // Exponents are Equal
{
output.insertTermAtFront(X.retrieve().Coefficient+
Y.retrieve().Coefficient,
X.retrieve().Exponent);
X.advance();
Y.advance();
}
} // end of the while loop
216
POLYNOMIAL ADDITION
// copy any remaining terms
while(!X.isPastEnd()) {
output.insertTermAtFront(X.retrieve().Coefficient,
X.retrieve().Exponent);
X.Advance();
}
while(!Y.isPastEnd()) {
output.insertTermAtFront(Y.retrieve().Coefficient,
Y.retrieve().Exponent);
Y.Advance();
}
// At this point output is in reverse order
output.terms.Reverse(); // reversal of the list
return (output);
}
217
REVERSING A LIST
( 1,2,3,4,5,6,7,8) (8,7,6,5,4,3,2,1)
218
REVERSING A LIST
( 1,2,3,4,5,6,7,8) (8,7,6,5,4,3,2,1)
219
REVERSING A LIST
ListNode<Object> *current,*previous;
current = NULL;
previous = NULL;
// in place reversal of a list
// uses two additional pointers
ListNode<Object> *current,*previous;
current = NULL;
previous = NULL; current
// in place reversal of a list
// uses two additional pointers
ListNode<Object> *current,*previous;
current = NULL;
previous = NULL; current
// in place reversal of a list
// uses two additional pointers
ListNode<Object> *current,*previous;
current = NULL;
previous = NULL; current
// in place reversal of a list
// uses two additional pointers
ListNode<Object> *current,*previous;
current = NULL;
previous = NULL; current
// in place reversal of a list
previous
// uses two additional pointers
ListNode<Object> *current,*previous;
current = NULL;
previous = NULL;
// in place reversal of a list
previous
// uses two additional pointers
current
while (header->next != NULL) {
current = header->next;
header->next =
header->next->next;
current ->next = previous;
previous = current;
}
header->next = previous;
}
226
REVERSING A LIST
header
template <class Object>
void List<Object>::Reverse()
{ 1 2 3
ListNode<Object> *current,*previous;
current = NULL;
previous = NULL;
// in place reversal of a list
previous
// uses two additional pointers
current
while (header->next != NULL) {
current = header->next;
header->next =
header->next->next;
current ->next = previous;
previous = current;
}
header->next = previous;
}
227
REVERSING A LIST
header
template <class Object>
void List<Object>::Reverse()
{ 1 2 3
ListNode<Object> *current,*previous;
current = NULL;
previous = NULL;
// in place reversal of a list
previous
// uses two additional pointers
current
while (header->next != NULL) {
current = header->next;
header->next =
header->next->next;
current ->next = previous;
previous = current;
}
header->next = previous;
}
228
REVERSING A LIST
header
template <class Object>
void List<Object>::Reverse()
{ 1 2 3
ListNode<Object> *current,*previous;
current = NULL;
previous = NULL;
// in place reversal of a list
previous
// uses two additional pointers
current
while (header->next != NULL) {
current = header->next;
header->next =
header->next->next;
current ->next = previous;
previous = current;
}
header->next = previous;
}
229
REVERSING A LIST
header
template <class Object>
void List<Object>::Reverse()
{ 1 2 3
ListNode<Object> *current,*previous;
current = NULL;
previous = NULL;
// in place reversal of a list
previous
// uses two additional pointers
current
while (header->next != NULL) {
current = header->next;
header->next =
header->next->next;
current ->next = previous;
previous = current;
}
header->next = previous;
}
230
REVERSING A LIST
header
template <class Object>
void List<Object>::Reverse()
{ 1 2 3
ListNode<Object> *current,*previous;
current = NULL;
previous = NULL;
// in place reversal of a list
previous
// uses two additional pointers
current
while (header->next != NULL) {
current = header->next;
header->next =
header->next->next;
current ->next = previous;
previous = current;
}
header->next = previous;
}
231
REVERSING A LIST
header
template <class Object>
void List<Object>::Reverse()
{ 1 2 3
ListNode<Object> *current,*previous;
current = NULL;
previous = NULL;
// in place reversal of a list
previous
// uses two additional pointers
current
while (header->next != NULL) {
current = header->next;
header->next =
header->next->next;
current ->next = previous;
previous = current;
}
header->next = previous;
}
232
REVERSING A LIST
header
template <class Object>
void List<Object>::Reverse()
{ 1 2 3
ListNode<Object> *current,*previous;
current = NULL;
previous = NULL;
// in place reversal of a list
previous
// uses two additional pointers
current
while (header->next != NULL) {
current = header->next;
header->next =
header->next->next;
current ->next = previous;
previous = current;
}
header->next = previous;
}
233
REVERSING A LIST
header
template <class Object>
void List<Object>::Reverse()
{ 1 2 3
ListNode<Object> *current,*previous;
current = NULL;
previous = NULL;
// in place reversal of a list
previous
// uses two additional pointers
current
while (header->next != NULL) {
current = header->next;
header->next =
header->next->next;
current ->next = previous;
previous = current;
}
header->next = previous;
}
234