The List ADT Reading: Sections 3.2, 3.3, 3.5.

Slides:



Advertisements
Similar presentations
Stacks, Queues, and Linked Lists
Advertisements

DATA STRUCTURES AND ALGORITHMS Prepared by İnanç TAHRALI
1 Linked lists Sections 3.2, 3.3, 3.5 Chapter 3 Lists, Stacks, and Queues Abstract Data Types, Vectors.
Lists A list is a finite, ordered sequence of data items. Important concept: List elements have a position. Notation: What operations should we implement?
1111 Abstract Data Types Cpt S 223. School of EECS, WSU.
CSE Lecture 12 – Linked Lists …
Linked Lists CENG 213 Data Structures.
Copyright © 2008 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Starting Out with C++ Early Objects Sixth Edition Chapter 17: Linked Lists.
Starting Out with C++: Early Objects 5/e © 2006 Pearson Education. All Rights Reserved Starting Out with C++: Early Objects 5 th Edition Chapter 17 Linked.
Data Structures Using C++ 2E
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Starting Out with C++ Early Objects Seventh Edition by Tony Gaddis, Judy.
1 Chapter 3 Lists, Stacks, and Queues Abstract Data Types, Vectors Sections 3.1, 3.2, 3.3, 3.4 Abstract Data Types (ADT) Iterators Implementation of Vector.
1 Joe Meehean.  Conceptual Picture N items chained together using pointers pointed to by head variable  Advantage allows list to grow indefinitely without.
C++ Classes and Data Structures Jeffrey S. Childs
CNS  Sequences  vector,deque,list,(string),forward_list  Container Adapters  queue, stack, priority_queue  Associative Containers  set, unordered_set.
Generic Positional Containers and Double-Ended Queues.
DATA STRUCTURES AND ALGORITHMS Lecture Notes 4 Prepared by İnanç TAHRALI.
CMSC 341 Linked Lists, Stacks and Queues. 8/3/2007 UMBC CMSC 341 LSQ 2 Implementing Your Own Linked List To create a doubly linked list as seen below.
Prof. amr Goneid, AUC1 CSCE 110 PROGRAMMING FUNDAMENTALS WITH C++ Prof. Amr Goneid AUC Part 16. Linked Lists.
Slide 1 Linked Data Structures. Slide 2 Learning Objectives  Nodes and Linked Lists  Creating, searching  Linked List Applications  Stacks, queues.
A Generic List Class and Linked Lists Andy Wang Data Structures, Algorithms, and Generic Programming.
1 Data Structures CSCI 132, Spring 2014 Lecture 20 Linked Lists.
Lists Chapter 8. 2 Linked Lists As an ADT, a list is –finite sequence (possibly empty) of elements Operations commonly include: ConstructionAllocate &
Starting Out with C++ Early Objects Seventh Edition by Tony Gaddis, Judy Walters, and Godfrey Muganda Chapter 17: Linked Lists.
Copyright © 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Slide
Copyright © 2012 Pearson Education, Inc. Chapter 17: Linked Lists.
Copyright © 2002 Pearson Education, Inc. Slide 1.
A Doubly Linked List prevnextdata There’s the need to access a list in reverse order header dnode.
Linked lists. Data structures to store a collection of items Data structures to store a collection of items are commonly used Typical operations on such.
Chapter 6 LISTS AND STRINGS 1. List Definition 2. List Implementations (a) Class Templates (b) Contiguous (c) Simply Linked (d) Doubly Linked 3. Linked.
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Starting Out with C++ Early Objects Seventh Edition by Tony Gaddis, Judy.
1 Chapter 3 Lists, Stacks, and Queues Reading: Sections 3.1, 3.2, 3.3, 3.4 Abstract Data Types (ADT) Iterators Implementation of Vector.
11/07/141 Abstract Data Types (ADTs) An abstract data type (ADT) is an abstraction of a data structure An ADT specifies: –Data stored –Operations on the.
Chapter 17: Linked Lists. Objectives In this chapter, you will: – Learn about linked lists – Learn the basic properties of linked lists – Explore insertion.
1 Linked Lists Assignment What about assignment? –Suppose you have linked lists: List lst1, lst2; lst1.push_front( 35 ); lst1.push_front( 18 ); lst2.push_front(
1 Circular, Doubly-Linked Lists Node Composition List Class Pushing and Popping Values Insert and Erase at Arbitrary Locations List Implementation.
Abstract Data Type (ADT) &List (Part II) Lecture Objectives Implement linked list using pointers Concept of iterators STL's list class Other variations.
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Starting Out with C++ Early Objects Seventh Edition by Tony Gaddis, Judy.
Copyright © 2014, 2008 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Starting Out with C++ Early Objects Eighth Edition by Tony Gaddis,
1 Generic Positional Containers and Double-Ended Queues.
List Structures What is a list? A homogeneous collection of elements with a linear relationship between the elements linear relationship - each element.
Data Structure and Algorithm Analysis 03: Lists, Stacks and Queues Hongfei Yan School of EECS, Peking University.
1 Trees 3: The Binary Search Tree Reading: Sections 4.3 and 4.6.
Dale Roberts Department of Computer and Information Science, School of Science, IUPUI CSCI 240 Abstract Data Types Queues Dale Roberts, Lecturer
Chapter 16: Linked Lists.
C++ Programming:. Program Design Including
Cpt S 122 – Data Structures Abstract Data Types
The List ADT Sections 3.2, 3.3, 3.5 Introduction
A Doubly Linked List There’s the need to access a list in reverse order prev next data dnode header 1.
Chapter 4 Linked Lists
Chapter 16-2 Linked Structures
Abstract Data Types Iterators Vector ADT Sections 3.1, 3.2, 3.3, 3.4
Linked Lists, Stacks and Queues Textbook Sections
Object Oriented Programming COP3330 / CGS5409
Chapter 4 Linked Lists.
Generic Positional Containers and Double-Ended Queues
Chapter 18: Linked Lists.
Chapter 3 Lists, Stacks, and Queues Abstract Data Types, Vectors
[Chapter 4; Chapter 6, pp ] CSC 143 Linked Lists [Chapter 4; Chapter 6, pp ]
Doubly Linked List Implementation
Recursive Linked List Operations
Chapter 4 Linked Lists.
Chapter 17: Linked Lists.
Lists - I The List ADT.
Lists - I The List ADT.
Copyright © – Curt Hill STL List Details Copyright © – Curt Hill.
Doubly Linked List Implementation
Chapter 3 Lists, Stacks, and Queues
The List Container and Iterators
Data Structures & Programming
Presentation transcript:

The List ADT Reading: Sections 3.2, 3.3, 3.5

Lists in Everyday Life Shopping list To-do list Dave Letterman’s top 10 list Shopping vector? What if you want to insert or delete an item? How many elements you need to move?

List Wish List Efficiently insert an element Efficiently remove an element Remove all items Assignment operator Comparison operators Constructors/destructors Generic class Convenient way to iterate through the list

Abstract view of List and Iterator Doubly-linked list ListElement next next next next null null prev prev prev prev front back I1 Iterator

List Public Interface Constructors and big-five Copy/move constructor, copy/move assignment operator, destructor List(); List(const List &rhs); List(List &&rhs); List & operator=(const List &rhs); List & operator=(List && rhs); ~List(); Read-only accessor functions int size() const; bool empty() const;

List Public Interface (cont’d) Accessing values on the list Object & front(); Object & back(); and their constant versions. Locating places on the list using iterators Both regular and constant versions iterator begin(); const_iterator begin() const; iterator end(); const_iterator end() const;

List Public Interface (cont’d) List manipulation functions int push_front(const Object & x); int push_back(const Object & x); int pop_front(); int pop_back(); iterator insert(iterator & itr, const Object & x); iterator erase( iterator itr); iterator erase( iterator start, iterator end ); void clear(); // and move versions, where it is applicable

List Complexity Requirements O(1) Runtime complexity Default constructor Move constructor Move assignment operator= push_front(t), push_back(t), insert(I, t) pop_front(), pop_back(), erase(I) begin(), end(); front(), back(); empty();

List Complexity Requirements (2) O(N) Runtime complexity Copy Constructor Copy assignment operator= Destructor clear() erase(SI,EI)

List Iterator Public Interface Read-only operators bool operator== (const iterator & rhs) const; bool operator!= (const iterator & rhs) const; Object & operator* ( ) const; // return a reference to current value Write operators iterator & operator++ ( ); // prefix iterator operator++ ( int ); // postfix iterator& operator-- ( ); // prefix iterator operator-- ( int ); // postfix O(1) requirement for space and time

Using List List<string> Cities; Cities.push_front(“Tallahassee”); “Tallahassee” Cities.push_back(“Gainesville”); “Tallahassee”, “Gainesville” Cities.push_front(“Jacksonville”); “Jacksonville”, “Tallahassee”, “Gainesville” Cities.push_back(“Miami”); “Jacksonville”, “Tallahassee”, “Gainesville”, “Miami” List<string>::iterator I; for (I = Cities.begin(); I != Cities.end(); ++I) { // print list with << } // C++11 for (auto I = Cities.begin(); I != Cities.end(); ++I) { … for (const auto & city : Cities) {

List Insertion Insert “Orlando” before “Miami” // sequential search for (auto I = Cities.begin(); I != Cities.end(); ++I) { if (“Miami” == *I) { break; } // insert the new string Cities.insert(I, “Orlando”); “Jacksonville”, “Tallahassee”, “Gainesville”, “Orlando”, “Miami” // what happens if “Miami” is not on the list?

Remove all copies of an item from List Remove all elements with value “Orlando” List<string>::iterator I = Cities.begin(); // auto I = Cities.begin(); // c++11 while( I != Cities.end()) { if (“Orlando” == *I) { I = Cities.erase(I); } else { I++; }

List and List Iterator Conceptual relationship Iterator I1 begin current end List: A, B, C, D, E, F Iterator I2

List Implementation A Doubly Linked List With Header and Tail Nodes as Markers An Empty List

Nodes in a list Node Defined within the List class, with limited scope Data Value Pointers to the previous and next element Defined within the List class, with limited scope data prev next data prev next data prev next No need for contiguous memory allocation

List Class (Part 1) template <typename Object> class List { private: struct Node Object data; Node *prev; Node *next; Node( const Object & d = Object{ }, Node * p = nullptr, Node * n = nullptr ) : data{ d }, prev{ p }, next{ n } { } Node( Object && d, Node * p = nullptr, Node * n = nullptr ) : data{ std::move( d ) }, prev{ p }, next{ n } { } };

List Class (Part 2) public: class const_iterator { const_iterator( ) : current{ nullptr } // Public constructor for const_iterator. { } const Object & operator* ( ) const { return retrieve( ); } const_iterator & operator++ ( ) // prefix current = current->next; return *this; } const_iterator operator++ ( int ) // postfix const_iterator old = *this; ++( *this ); return old;

List Class (Part 3) const_iterator & operator-- ( ) { current = current->prev; return *this; } const_iterator operator-- ( int ) const_iterator old = *this; --( *this ); return old; bool operator== ( const const_iterator & rhs ) const { return current == rhs.current; } bool operator!= ( const const_iterator & rhs ) const { return !( *this == rhs ); } protected: Node *current; Object & retrieve( ) const { return current->data; } const_iterator( Node *p ) : current{ p } { } friend class List<Object>; };

List Class (Part 4) Why do we override the parent’s * implementation? class iterator : public const_iterator { public: iterator( ) { } Object & operator* ( ) { return const_iterator::retrieve( ); } const Object & operator* ( ) const { return const_iterator::operator*( ); } iterator & operator++ ( ) this->current = this->current->next; return *this; } iterator operator++ ( int ) iterator old = *this; ++( *this ); return old; Why do we override the parent’s * implementation? Why do we override the parent’s ++ implementation?

List Class (Part 5) iterator & operator-- ( ) { this->current = this->current->prev; return *this; } iterator operator-- ( int ) iterator old = *this; --( *this ); return old; protected: iterator( Node *p ) : const_iterator{ p } { } friend class List<Object>; };

List Class (Part 6) public: List( ) { init( ); } ~List( ) { clear( ); delete head; delete tail; } List( const List & rhs ) // copy constructor init( ); for( auto & x : rhs ) push_back( x ); List & operator= ( const List & rhs ) // copy assignment operator= List copy = rhs; std::swap( *this, copy ); return *this;

List Class (Part 7) List( List && rhs ) // move constructor : theSize{ rhs.theSize }, head{ rhs.head }, tail{ rhs.tail } { rhs.theSize = 0; rhs.head = nullptr; rhs.tail = nullptr; } List & operator= ( List && rhs ) // move assignment operator= std::swap( theSize, rhs.theSize ); std::swap( head, rhs.head ); std::swap( tail, rhs.tail ); return *this; iterator begin( ) { return iterator( head->next ); } const_iterator begin( ) const { return const_iterator( head->next ); }

List Class (Part 8) iterator end( ) { return iterator( tail ); } const_iterator end( ) const { return const_iterator( tail ); } int size( ) const { return theSize; } bool empty( ) const { return size( ) == 0; } void clear( ) { while( !empty( ) ) pop_front( ); } Object & front( ) { return *begin( ); } const Object & front( ) const

List Class (Part 9) Object & back( ) { return *--end( ); } const Object & back( ) const void push_front( const Object & x ) // copy { insert( begin( ), x ); } void push_back( const Object & x ) // copy { insert( end( ), x ); } void push_front( Object && x ) // move { insert( begin( ), std::move( x ) ); } void push_back( Object && x ) // move { insert( end( ), std::move( x ) ); } void pop_front( ) { erase( begin( ) ); } void pop_back( ) { erase( --end( ) ); }

List Class (Part 10) iterator insert( iterator itr, const Object & x ) { Node *p = itr.current; ++theSize; return iterator( p->prev = p->prev->next = new Node{ x, p->prev, p } ); } iterator insert( iterator itr, Object && x ) return iterator( p->prev = p->prev->next = new Node{ std::move( x ), p->prev, p } );

List Class (Part 10) iterator erase( iterator itr ) { Node *p = itr.current; iterator retVal( p->next ); p->prev->next = p->next; p->next->prev = p->prev; delete p; --theSize; return retVal; } iterator erase( iterator from, iterator to ) for( iterator itr = from; itr != to; ) itr = erase( itr ); return to;

List Class (Part 11) private: int theSize; Node *head; Node *tail; void init( ) { theSize = 0; head = new Node; tail = new Node; head->next = tail; tail->prev = head; } };

Reading assignment Sections 3.6 and 3.7 A problem to consider Assuming that we do not maintain theSize member variable, how do we determine the number of elements in a list using a recursive function?