CMSC 341.

Slides:



Advertisements
Similar presentations
Chapter 22 Implementing lists: linked implementations.
Advertisements

DATA STRUCTURES AND ALGORITHMS Prepared by İnanç TAHRALI
Linked Lists CENG 213 Data Structures.
DATA STRUCTURES AND ALGORITHMS Lecture Notes 9 Prepared by İnanç TAHRALI.
The Template Class Chain Chain Linear list. Each element is stored in a node. Nodes are linked together using pointers.
CMSC 341 Lists 3. 2 Doubly-Linked Lists Option: add pointer to previous node Issues –doubles number of pointers –allows immediate (O(1)) access to previous.
C++ Classes and Data Structures Jeffrey S. Childs
DATA STRUCTURES AND ALGORITHMS Lecture Notes 4 Prepared by İnanç TAHRALI.
BINARY SEARCH TREE. Binary Trees A binary tree is a tree in which no node can have more than two children. In this case we can keep direct links to the.
STL multimap Container. STL multimaps multimaps are associative containers –Link a key to a value –AKA: Hashtables, Associative Arrays –A multimap allows.
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson Education, Inc. All rights reserved Stacks.
Lab05. // // // Laboratory 5 ListLinked.h // // Class declaration for the linked implementation.
ICOM 4035 – Data Structures Dr. Manuel Rodríguez Martínez Electrical and Computer Engineering Department.
M180: Data Structures & Algorithms in Java Linked Lists Arab Open University 1.
M180: Data Structures & Algorithms in Java Linked Lists – Part 2 Arab Open University 1.
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.
The List ADT Reading: Sections 3.2, 3.3, 3.5.
ICOM 4035 – Data Structures Dr. Manuel Rodríguez Martínez Electrical and Computer Engineering Department.
Nirmalya Roy School of Electrical Engineering and Computer Science Washington State University Cpt S 223 – Advanced Data Structures C++ Review 2.
IKI 10100I: Data Structures & Algorithms Ruli Manurung (acknowledgments to Denny & Ade Azurat) 1 Fasilkom UI Ruli Manurung (Fasilkom UI)IKI10100: Data.
IKI 10100: Data Structures & Algorithms Ruli Manurung (acknowledgments to Denny & Ade Azurat) 1 Fasilkom UI Ruli Manurung (Fasilkom UI)IKI10100: Lecture1.
CSCI  Sequence Containers – store sequences of values ◦ vector ◦ deque ◦ list  Associative Containers – use “keys” to access data rather than.
Linked Lists A formal data structure. Linked Lists Collections of data items “lined up in a row” Inserts and deletes can be done anywhere in the list.
1 Trees 3: The Binary Search Tree Reading: Sections 4.3 and 4.6.
Chapter (3) - Lists, Stacks, and Queues
Class: Special Topics Copy Constructors Static members Friends this
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
LinkedList Class.
Doubly linked lists.
Chapter 16-2 Linked Structures
Trees 3: The Binary Search Tree
Linked Lists.
Chapter 4 Linked Lists.
Deques, Stacks and Queues
CMSC 341 Binary Search Trees 11/19/2018.
CS 302 Data Structures Linked Lists.
CMSC 341 Hashing 12/2/2018.
CMSC 341 Binary Search Trees.
[Chapter 4; Chapter 6, pp ] CSC 143 Linked Lists [Chapter 4; Chapter 6, pp ]
CMSC 341.
CMSC 341 Binary Search Trees 1/3/2019.
Doubly Linked List Implementation
Chapter 4 Linked Lists.
CMSC 341 Hashing 2/18/2019.
CMSC 341 Lists 3.
CMSC 341 Lists 3.
CMSC 341 Binary Search Trees 2/23/2019.
CMSC 341.
Lists - I The List ADT.
Lists - I The List ADT.
CMSC 341 Binary Search Trees.
Chapter 8: Class Relationships
CMSC 341 Hashing 4/11/2019.
CMSC 341 Stacks and Queues 4/17/2019.
CMSC 341 Stacks and Queues 4/17/2019.
CMSC 341 Stacks and Queues 4/29/2019.
CMSC 341 Hashing 4/27/2019.
Lists - I The List ADT.
CMSC 341 List 2.
CMSC 341 Lecture 7.
CMSC 341 Binary Search Trees 5/8/2019.
Lists - I The List ADT.
Lists CMSC 202, Version 4/02.
CMSC 341 Binary Search Trees 5/28/2019.
Lists CMSC 202, Version 4/02.
Doubly Linked List Implementation
CMSC 341 Lecture 12.
Abstract Data Types ADT: A set of objects and a set of operations on those objects. examples: integers: +, - , *, … Collection, insert, remove, … set:
CMSC 341 Binary Search Trees 2/21/2006.
Presentation transcript:

CMSC 341

List.H template <class Object> class List { public: List(); List(const List &rhs); ~List(); const List &operator=(const List &rhs); Bool isEmpty() const; void makeEmpty(); void remove (const Object &x); void insert (const Object &x, const ListIter<Object> &p);

List.H (cont) ListIter<Object> first()const; ListIter<Object> zeroth()const; void insert (const Object &x, const ListIter<Object> &p); ListIter<Object> find(const Object &x); ListIter<Object> findPrevious(const Object &x); private: ListNode<Object> *header; }; Linked list implementation Use header node to avoid special cases such as insertion on empty list

ListNode.H template <class Object> class ListNode { ListNode(const Object &theElement=Object(), ListNode *n = NULL) :element(theElement), next(n) {} Object element; ListNode *next; friend class List<Object>; friend class ListItr<Object>; }; Note: all fields are private. Accessible to friend classes. Constructor invoked as: ListNode() -- element will be the the object constructed by the no-argument constructor -- next will be NULL ListNode(const Object &theElement) -- element will be theElement ListNode(const Object& theElement, ListNode *n) -- element will theElement -- next will be n Note: no explicit copy constructor, assignment operator, or destructor

ListItr.H 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; ListItr(ListNode<Object> *theNode):current(theNode){} friend class List<Object>; } Keeps a pointer to the ListNode it considers the current one Keeps List as a friend so List can use ListItr’s private constructor The private constructor is the one used by List Why is there a public no-arg constructor? Because we want to be able to use Iterator as ordinary objects. For example, we might want to have a list of iterators over List of int List<ListItr<int>> All objects must have a zero arg constructor. For example, the ListNode used by this List of Iterators uses the no-arg constructor to intialize Note that the no-arg constructor of ListItr produces an iterator that is already exhausted (isPastEnd)

Linked List Implementation template <class Object> List<Object>::List() { header = new ListNode<Object>; } List<Object>::isEmpty() { return !(header->next); Constructs the empty list containing just the header node Asymptotic performance of isEmpty() =O(1) for best, worst, average

Linked List Implementation (cont) template <class Object> ListItr<Object> List<Object>::zeroth() { return ListItr<Object>(header); } ListItr<Object> List<Object>::first() { return ListItr<Object>(header->next); Uses private constructor for ListItr. It makes the iterator’s notion of current be the header node. Note: return by value. Why? Because the original in in local scope of the zeroth method. -------------------- Note: this is a valid iterator even on an empty list. It will be pastEnd

Linked List Implementation (cont) template <class Object> void List<Object>:: insert(const Object &x, const ListItr<Object> &p) { if (!p.isPastEnd()) //text uses p.current!=NULL p.current->next = new ListNode<Object>(x,p.current->next); } This is the only place a new ListNode is created (except for header node) If p does not belong to this list, will make a mess of some other list Asymptotic performance: O(1) best, worst, average Element of ListNode is stored as an Object, not a reference. Therefore the node stores a copy of the element passed to insert.

Linked List Implementation (cont) template <class Object> ListItr<Object> List<Object>:: find(const Object &x const) { ListNode<Object> *p = header->next; while (p!=NULL && p->element !=x) p = p->next; return ListItr<Object>(p); } Asymptotic performance: O(n) avg and worst O(1) best case (when x is the first element)

Linked List Implementation (cont) template <class Object> ListItr<Object> List<Object>:: findPrevious(const Object &x const) { ListNode<Object> *p = header; while (p->next!=NULL && p->next->element !=x) p = p->next; return ListItr<Object>(p); } Empty List: p remains pointed at header x not on list: the while loop moves p until it points to the last node on the list. Asymptotic performance O(n): avg and worst case O(1): best case (x is first element)

Linked List Implementation (cont) template <class Object> void List<Object>:: remove(const Object &x) { ListItr<Object> p=findPrevious(x); if (p.current->next != NULL){ ListNode<Object> *oldnode = p.current->next; p.current->next = p.current->next->next; delete oldnode; } Early on, p could refer to 1. The header if list is empty 2. The last node if x not on list 3. The node before x, otherwise The only place where regular (non-header) nodes get deleted. Asymptotic performance: O(n): avg and worst case because of call to findPrevious O(1) in best case (x first on list)

Linked List Implementation (cont) template <class Object> void List<Object>::makeEmpty() { while (!isEmpty()) remove (first().retrieve()); } Asymptotic performance: O(n) but remove is O(n) and it is called n times. How come it’s not O(n^2)? Because findPrevious,in remove, always finds the first node’s previous in O(1). So. In this case, remove (the best case) is O(1) and makeEmpty = O(n). Note -- a new first iterator is constructed in each iteration. Must do that because the previous iteration goes stale when the node is deleted. Perhaps could do: while (!isEmpty()) remove(header->next->element)

Linked List Implementation (cont) template <class Object> void List<Object>::~List() { makeEmpty(); //deletes all nodes except header delete header; } Asymptotic performance: O(n)

Linked List Implementation (cont) template <class Object> const List<Object>& List<Object>:: operator= (const List<Object> &rhs) { if (this != &rhs){ makeEmpty(); ListItr<Object> ritr = rhs.first(); ListItr<Object> itr = zeroth(); while (!ritr.isPastEnd()) { insert(ritr.retrieve(), itr); ritr.advance(); itr.advance(); } return *this; Remember: insert stores a copy of the element. Thereform, assignment is deep copy. Asymptotic performance (lhs n1, rsh n2): makeEmpty: O(n1) iteration over rhs: O(n2) = O(n1) + O(n2) = O(max(n1,n2))