Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators...

31
Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked list the need for a deep copy 2 Iterators on List nested classes for iterator function objects MCS 360 Lecture 12 Introduction to Data Structures Jan Verschelde, 25 September 2017 Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 1 / 31

Transcript of Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators...

Page 1: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

Iterators

1 Double Linked and Circular Listsnode UML diagramimplementing a double linked listthe need for a deep copy

2 Iterators on Listnested classes for iteratorfunction objects

MCS 360 Lecture 12Introduction to Data Structures

Jan Verschelde, 25 September 2017

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 1 / 31

Page 2: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

Iterators

1 Double Linked and Circular Listsnode UML diagramimplementing a double linked listthe need for a deep copy

2 Iterators on Listnested classes for iteratorfunction objects

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 2 / 31

Page 3: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

Linked Lists

A linked list is a sequence of nodes connected by pointers.

We distinguish four types:1 single linked list: one pointer to next node2 double linked list: pointer to next and previous3 circular list: last next points to first node4 ordered list: if data type admits order

The list in the Standard Template Library (STL) is double linked.The slist in the STL is a single linked list.

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 3 / 31

Page 4: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

Unified Modeling Language

The node UML diagram of a double linked list:

Node

Item_Type data

nextprev

The type of the data is templated,

next points to the next node in the list,prev points to the previous node in the list.

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 4 / 31

Page 5: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

doubly linking nodes

A linked list to store 3, 5, 4 looks like:

Node

next: *prev: *data: 3

�NULL

� Node

next: *prev: *data: 5

� � Node

next: *prev: *data: 4

� � NULL

At the expense of one extra pointer per node,reverse transversal becomes efficient.

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 5 / 31

Page 6: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

a circular list

A circular list to store 3, 5, 4 looks like:

Node

next: *data: 3

� Node

next: *data: 5

� Node

next: *data: 4

Traversing a circular list is like modular addition,e.g.: n times nd = nd->next on a node ndin a list of length n leads to the same node nd.

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 6 / 31

Page 7: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

Iterators

1 Double Linked and Circular Listsnode UML diagramimplementing a double linked listthe need for a deep copy

2 Iterators on Listnested classes for iteratorfunction objects

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 7 / 31

Page 8: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

file mcs360_double_list.h#ifndef MCS360_DOUBLE_LIST_H#define MCS360_DOUBLE_LIST_H#define NULL 0

namespace mcs360_double_list{

template <typename T>class List{

private:#include "mcs360_double_node.h"Node *first; // points to first nodeNode *last; // points to last node

public: // operations omitted};

}#include "mcs360_double_list.tc"#endif

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 8 / 31

Page 9: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

file mcs360_double_node.h

#ifndef DNODE_H#define DNODE_H

struct Node{

T data; // T is template parameterNode *next; // pointer to next nodeNode *prev; // pointer to previous node

Node(const T& item, Node* next_ptr = NULL,Node* prev_ptr = NULL) :data(item), next(next_ptr),prev(prev_ptr) {}

};#endif

The struct of C is a class where all is public.

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 9 / 31

Page 10: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

public methods

In file mcs360_double_list.h:

public:

List();List(T item);void append(T item);void write_forward();void write_backward();

These methods form a very basic, first implementation.

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 10 / 31

Page 11: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

constructors in the file mcs360_double_list.tc

namespace mcs360_double_list{

template <typename T>List<T>::List(){

first = NULL;last = NULL;

}

template <typename T>List<T>::List(T item){

first = new Node(item);last = first;

}

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 11 / 31

Page 12: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

a double linked list

Appending to a list that stores 3, 5, 4:

first

Node

next: *prev: *data: 3

�NULL

� Node

next: *prev: *data: 5

� �

last

Node

next: *prev: *data: 4

� � NULL

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 12 / 31

Page 13: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

the append() method

template <typename T>void List<T>::append(T item) {

if(first == NULL) {first = new Node(item);last = first;

}else if(first == last) {

first->next = new Node(item);first->next->prev = first;last = first->next;

} else {last->next = new Node(item);last->next->prev = last;last = last->next;

}}

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 13 / 31

Page 14: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

traversing forward and backward

template <typename T>void List<T>::write_forward(){

Node *ptr = first;while(ptr != NULL) {

std::cout << "->" << ptr->data;ptr = ptr->next;

}}template <typename T>void List<T>::write_backward(){

Node *ptr = last;while(ptr != NULL) {

std::cout << "->" << ptr->data;ptr = ptr->prev;

}}

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 14 / 31

Page 15: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

Iterators

1 Double Linked and Circular Listsnode UML diagramimplementing a double linked listthe need for a deep copy

2 Iterators on Listnested classes for iteratorfunction objects

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 15 / 31

Page 16: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

testing the class

#include "mcs360_double_list.h"#include <iostream>using namespace std;using namespace mcs360_double_list;

int main(){

List<int> L(3);

L.append(5);L.append(4);cout << " forward write :";L.write_forward();cout << endl;cout << "backward write :";L.write_backward();cout << endl;

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 16 / 31

Page 17: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

the need for a deep copy

List<int> K = L;L.append(1);cout << " writing K after K = L :";K.write_forward(); cout << endl;cout << " writing L after K = L :";L.write_forward(); cout << endl;

The assignment K = L is the shallow copy of pointers first andlast⇒ as L changes, so does K.

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 17 / 31

Page 18: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

Iterators

1 Double Linked and Circular Listsnode UML diagramimplementing a double linked listthe need for a deep copy

2 Iterators on Listnested classes for iteratorfunction objects

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 18 / 31

Page 19: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

iterators on list

Including write_forward and write_backward in definition of ourclass is not proper.

In our test program we would like to use

void write_with_iterator ( List<int> L ){

for(List<int>::Iterator item = L.begin();item != L.end(); ++item)

cout << "->" << *item;cout << endl;

}

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 19 / 31

Page 20: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

nested classes

With templates everything must be included in the header file, heremcs360_double_list.h.

#include <stdexcept>

namespace mcs360_double_list{

// omitted private partpublic: // omitted previous public

#include "mcs360_list_iterator.h"friend class Iterator;

The class Iterator must have access to the private part of List,therefore: friend.

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 20 / 31

Page 21: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

the class Iterator

#ifndef MCS360_LIST_ITERATOR_H#define MCS360_LIST_ITERATOR_H

class Iterator{

friend class List<T>;private:

List<T> *parent; /* refers to the list */

typename List<T>::Node *current;/* pointer to the current node in parent */

Iterator( List<T> *L, Node *n ) :parent(L), current(n) {}

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 21 / 31

Page 22: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

the public part

T& operator*() const // dereferencing operator{

if(current == NULL)throw std::invalid_argument

("cannot dereference past end()");return current->data;

}Iterator& operator++() // prefix increment operator{

if(current == NULL)throw std::invalid_argument

("cannot go past end()");current = current->next;

}bool operator!=(const Iterator &other){

return current != other.current;}

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 22 / 31

Page 23: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

begin() and end()

At the end of mcs360_list_iterator.h, we put:

Iterator begin(){

Iterator r(this,this->first);return r;

}

Iterator end(){

Iterator r(this,NULL);return r;

}

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 23 / 31

Page 24: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

postfix increment operator

The postfix increment operator first makes a copy of the current valueof the iterator:

Iterator operator++(int)// postfix increment operator{

Iterator return_value = *this;++(*this);return return_value;

}

Observe the prefix increment operator:

Iterator& operator++()

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 24 / 31

Page 25: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

Iterators

1 Double Linked and Circular Listsnode UML diagramimplementing a double linked listthe need for a deep copy

2 Iterators on Listnested classes for iteratorfunction objects

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 25 / 31

Page 26: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

function objects

A frequent recurring application on sequences is to select items thatmatch a criterion.

Example: list all even numbers in a list.

To define the criterion we overload the function call operator, theoperator().

A class that overloads () is called a function classand an object of this class is a function object.

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 26 / 31

Page 27: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

class Divisible_By

class Divisible_By{

private:

int divisor;

public:

Divisible_By(int d) : divisor(d){}bool operator()(int x){

return x % divisor == 0;}

};

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 27 / 31

Page 28: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

the find_if method

The find_if method of the STL list class finds the first occurrence ofan item that satisfies a criterion.

template < typename T, typename P >T find_if( T first, T last, P pred );

If there is no item for which pred returns true,then last is returned.

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 28 / 31

Page 29: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

listing the even numbers

int main(){

list<int> L;const int n = 20;

srand(time(0));for(int i=0; i<n; i++)

L.push_back(rand() % 100);

cout << "L : ";write(L);cout << "the even numbers of L : "

<< endl;even_numbers(L); cout << endl;

return 0;}

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 29 / 31

Page 30: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

applying find_if

void even_numbers ( list<int> L ){

list<int>::iterator i = L.begin();

while(i != L.end()){

list<int>::iterator j;

j = find_if(i,L.end(),Divisible_By(2));

if(j == L.end()) break;

cout << " " << *j;

while(i != j) i++;i++;

}}

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 30 / 31

Page 31: Iterators - homepages.math.uic.eduhomepages.math.uic.edu/~jan/mcs360f17/iterators.pdf · Iterators 1 Double Linked and Circular Lists node UML diagram implementing a double linked

Summary + Exercises

Ended Chapter 4 on Sequential Containers.

Exercises:

1 Define a copy operation on a double linked list.Show with a test program that the copy is deep: the original listdoes not change if the copy changes.

2 Write code for to insert item1 in a double linked list beforeitem2. If item2 does not occur in the list, then item1 isappended to the list.

3 Define a prefix decrement operator on the iterator. Write aprogram to write a list in reverse order.

4 Use the STL list and vector classes and give code to convert a listinto a vector and vice versa.

Introduction to Data Structures (MCS 360) Iterators L-12 25 September 2017 31 / 31