Chapter 7: The List ADT
description
Transcript of Chapter 7: The List ADT
![Page 1: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/1.jpg)
Chapter 7: The List ADT
![Page 2: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/2.jpg)
• Chapter 7
– Lists• Overview
– The List ADT and its uses; dynamic memory allocation; programming with linked lists.
![Page 3: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/3.jpg)
Objectives• 1. Understanding and applying the List ADT.• 2. Implementing a List Class using an array.• 3. Implementing a List Class using a linked list.• 4. Using dynamic allocation and pointers in C++.• 5. Variations on the linked list.• 6. Creating a class with overloaded operators.
![Page 4: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/4.jpg)
The List ADT• Characteristics:• A List L stores items of some type, called
ListElementType.• Operations:• void L.insert(ListElementType elem)• Precondition: None.• Postcondition:Lpost = Lpre with an instance
of elem added to Lpost.
![Page 5: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/5.jpg)
List ADT, first• bool L.first(ListElementType &elem)• Precondition: None• Postcondition:If the list is empty, none.
Otherwise, the variable elem contains the first item in L; the “next” item to be returned is the second in L.
• Return: true if and only if there is at least one element in L.
![Page 6: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/6.jpg)
List ADT, next• bool L.next(ListElementType &elem)• Precondition: The “first” operation has
been called at least once.• Postcondition:Variable elem contains the
next item in L, if there is one, and the next counter advances by one; if there is no next element, none.
• Return: true if and only if there is a next item.
![Page 7: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/7.jpg)
A useful exercise
• Define some additional operations that might be useful for a List ADT.
![Page 8: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/8.jpg)
List traversal• The process of accessing each item
in the list• Can be defined in terms of two other
operations– Accessing the first element in a list– Accessing the next element in a list
![Page 9: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/9.jpg)
Implementing lists• A header file for the list ADT
– cx7-1.h (on author’s web page)– See next slide
• Must include List ADT– characteristics– operations
![Page 10: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/10.jpg)
Code Example 7-1• // Code Example 7-1: List ADT header file• #include "dslib.h"• // the type of the individual elements in list is defined here• typedef int ListElementType;• // implementation specific stuff here• class List {• public:• List();• void insert(const ListElementType & elem);• bool first(ListElementType & elem);• bool next(ListElementType & elem);• private:• // implementation specific stuff here • };
![Page 11: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/11.jpg)
List();
• Is the list copy constructor• With no parameters or body it is a
‘default constructor’
![Page 12: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/12.jpg)
void insert(const ListElementType & elem);
• & means pass by reference– Value parameters should only be used for
simple types (int, char, etc.) which have simple copy constructors.
– For more complex data types, avoid the copy constructor by passing it by address
• const means the element cannot be modified in this function
![Page 13: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/13.jpg)
Lists using arrays• The simplest method to implement a
List ADT is to use an array• “linear list”, “contiguous list”• Characteristics are
– Array for storing entries (listArray)– numberOfElements– currentPosition
![Page 14: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/14.jpg)
Header file for array list• // cx7-2.h• #include "dslib.h"• // the type of the individual elements in the list is
defined here
• typedef int ListElementType;
• // the maximum size for lists is defined here
• const int maxListSize = 1000;
![Page 15: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/15.jpg)
Code Example 7-2• class List {• public:• List();• void insert(const ListElementType & elem);• bool first(ListElementType & elem);• bool next(ListElementType & elem);• private:• ListElementType listArray[maxListSize];• int numberOfElements;• int currentPosition;• };
![Page 16: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/16.jpg)
Array List Constructor• // cx7-3.cpp• #include "cx7-2.h"
• List::List()• {• // initialize to an empty list• numberOfElements = 0;• currentPosition = -1;• }
![Page 17: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/17.jpg)
Insertion into linear list• void List::insert(const ListElementType & elem)• {• assert(numberOfElements < maxListSize);• listArray[numberOfElements] = elem;• numberOfElements++; }
![Page 18: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/18.jpg)
Iterator function: first• bool List::first(ListElementType & elem)• {• if (numberOfElements == 0)• return false;• else {• currentPosition = 0;• elem = listArray[currentPosition];• return true;• }• }
![Page 19: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/19.jpg)
Iterator function: next• bool List::next(ListElementType & elem)• {• // currentPosition should always be• // greater than or equal to zero• assert(currentPosition >= 0);• if (currentPosition >= numberOfElements - 1)• return false;• else {• currentPosition++;• elem = listArray[currentPosition];• return true; }• }
![Page 20: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/20.jpg)
Simple List Client• // cx7-4.cpp• #include "cx7-2.h" // header for Linear List;
ListElementType is int• int main()• { List l;• ListElementType i; // header defines this as int• cout << "Enter items to add to list, or 0 to stop: ";• cin >> i;• while (i != 0) {• l.insert(i);• cin >> i; }
![Page 21: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/21.jpg)
Client main continued• cout << "Here are the items in the list.\n";• ListElementType elem;• bool notEmpty(l.first(elem));• while (notEmpty) {• cout << elem << endl;• notEmpty = l.next(elem);• }• return 0;• }
![Page 22: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/22.jpg)
Problems with arrays• Array implementations of lists use a static data
structure. Often defined at compile-time. Cannot be altered while program is running.
• This means we usually waste space rather than have program run out.
• It also means that data must be added to the end. If inserted in front, others must shuffle down. This is slow and inefficient.
![Page 23: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/23.jpg)
Figure 7-1
2 4 5 8 11 13 6
2 4 5 8 11 13 61
insert 1 here
0 1 2 3 4 5 6 7 8 9 10111213indices
![Page 24: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/24.jpg)
Linked list implementation• Data storage must now contain both
item and pointer to next item.• These are called ‘nodes’• This can be made dynamic• Much more efficient for insertion and
deletion
![Page 25: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/25.jpg)
Figure 7-2
7 12 5
![Page 26: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/26.jpg)
Figure 7-3
7 12 5
head
![Page 27: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/27.jpg)
Adding a node (insertion)• A four step process• Add at front of list
– Create new node– Copy data into it– Copy head into its link field– Copy node pointer to head
![Page 28: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/28.jpg)
Figure 7-4
7 12 5
9
head
![Page 29: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/29.jpg)
Figure 7-5
7 12 5
9
head
![Page 30: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/30.jpg)
Adding to end of list• A five step process
– Create new node– Copy data into it– Assign new node ptr to tail->link – Assign 0 to new node link (not NULL)– Assign new node ptr to tail
![Page 31: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/31.jpg)
Figure 7-6
7 12 5
9
headtail
![Page 32: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/32.jpg)
Figure 7-7
7 12 5
9
head
tail
![Page 33: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/33.jpg)
Algorithm 7-1: List Traversal
• Comment: Assume that “head” is the name of the external link to the list.
• current = head;• while current is not NULL {• process the node current points to;• current = the link field of the node
current points to;• }
![Page 34: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/34.jpg)
Linked list example• typedef int ListElementType;• class List {• // Use L to mean "this List"• public:• List();• // Precondition: None• // Postcondition: L is an empty List• void insert(const ListElementType & elem);• // Precondition: None• // Postcondition: Lpost = Lpre with an • // instance of elem added to Lpost
![Page 35: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/35.jpg)
First()• bool first(ListElementType & elem);• // Precondition: None• // Postcondition: If the list is empty, none. • // Otherwise, the variable • // elem contains the first item in L; • // the "next" item returned is the second in L.• // Returns: true, if and only if,• // there is at least one element in L.
![Page 36: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/36.jpg)
List class, public (con’t)• bool next(ListElementType & elem);• // Precondition: The "first" operation has been
called at least once.
• // Postcondition: Variable elem contains the next item in L, if there is one, and the next counter advances by one; if there is no next element, none.
• // Returns: true if and only if there was a next item.
![Page 37: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/37.jpg)
7.5 (con’t) private of next• private:• struct Node; // declaration without definition• typedef Node *Link; // use declaration of Node• struct Node { // now we define Node• ListElementType elem;• Link next;• };• Link head;• Link tail;• Link current;• };
![Page 38: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/38.jpg)
Linked list constructor
• List::List()• {• // Initialize an empty list• head = 0;• tail = 0;• current = 0;• }
![Page 39: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/39.jpg)
Insert for linked list• void List::insert(const ListElementType & elem)• {• Link addedNode(new Node);• assert(addedNode); // check whether node was allocated• addedNode->elem = elem;• if (head == 0) // list was empty -- set head• head = addedNode;• else• tail->next = addedNode;• tail = addedNode;• addedNode->next = 0;• }
![Page 40: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/40.jpg)
An easy mistake to make• //unsafe test of pointer with 0• int main() {• int * p; //p is a pointer to an int, initialized to 0• if (p = 0) //obviously, == was intended• cout << “zero pointer\n”;• else• cout << “non-zero pointer\n”;• return 0;• }
![Page 41: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/41.jpg)
Dynamic memory allocation• Use the ‘new’ operator instead of old C
calloc, malloc and realloc• This draws from the “free store”• Dynamic allocation occurs at run-time, not
compile time• To check on availability of memory use an
assertion.– link newNode = new Node;– assert(newNode);
![Page 42: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/42.jpg)
Linked list implementation
• List::List()• {• // Initialize an empty List• head = 0;• tail = 0;• current = 0;• }
![Page 43: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/43.jpg)
Code Example 7-8• void List::insert(const ListElementType & elem)• {• Link addedNode = new Node;• assert(addedNode); // check whether node was allocated• addedNode->elem = elem;• if (head == 0) // list was empty -- set head• head = addedNode;• else• tail->next = addedNode;• tail = addedNode;• addedNode->next = 0;• }
![Page 44: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/44.jpg)
First() method• bool List::first(ListElementType & elem)• {• // After calling first, current points to // first item in list• if (head == 0)• return false;• else {• elem = head->elem;• current = head;• return true;• }• }
![Page 45: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/45.jpg)
Next() method• bool List::next(ListElementType & elem)• {• // current should always be nonzero• assert(current); • // After each call, current points to the item• // that next has just returned.• if (current->next == 0)• return false;• else {• current = current->next;• elem = current->elem;• return true;• }• }
![Page 46: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/46.jpg)
Figure 7-8
7 12 5
7 12 5
head
head
current
currentelem next
elem next
![Page 47: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/47.jpg)
The Inorder List ADT• Many applications require that lists
be maintained in some order– Address books– File names– County records– Student records– Dictionary
![Page 48: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/48.jpg)
Inorder List requirements• Some part of the information stored
must be a designated key• For any two keys (k1, k2) there must
be a way to evaluate them, such as k1 < k2
• A ‘total order’ is any set of keys that obey an ordering rule.
![Page 49: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/49.jpg)
The Inorder List ADT• Characteristics:• An Inorder List L stores items of some
type (ListElementType) that is totally ordered.
• The items in the List are in order; that is, if a and b are elements of ListElement Type, and a < b, then if a and b are in L, a will be before b.
![Page 50: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/50.jpg)
Inorder List operations• Prerequisite:• ListElementType must work with the
operations <= and ==.• Operations:• void L.insert(const ListElementType &elem)• Precondition: None.• Postcondition:L = L with an instance of
elem added to the list
![Page 51: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/51.jpg)
First() method
• bool L.first(ListElementType &elem)• Precondition: None• Postcondition: If the list is empty, none.
Otherwise, the variable elem contains the smallest item in L; the “next” item to be returned is the second in L.
• Return: true if and only if there is at least one element in L.
![Page 52: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/52.jpg)
Next() method• bool L.next(ListElementType &elem)• Precondition: The “first” operation has
been called at least once.• Postcondition:Variable elem contains the
next item in L, in order, if there is one.• Return: true if and only if there is a next
item.
![Page 53: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/53.jpg)
Inorder invariant
u vinvariant: u < v
![Page 54: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/54.jpg)
Insertion (before)
7 12
9
![Page 55: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/55.jpg)
Insertion (after)
7 12
9
![Page 56: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/56.jpg)
Required insertion pointers
7 12
9predaddedNode
![Page 57: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/57.jpg)
Assertions (before insertion)
7 12
9predaddedNode
pred->elem pred->next pred->next->elem
addedNode->elem
Assertion: pred->elem <= addedNode->elem && addedNode->elem <= pred->next->elem
![Page 58: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/58.jpg)
Assertion (considering end-of-list)
• (pred->elem <= addedNode->elem) &&
• (addedNode->elem <= pred->next->elem || pred->next == 0).
![Page 59: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/59.jpg)
Assertion(after insertion)
7 12
9pred
pred->elem pred->next pred->next->next->elem
pred->next->elem
Assertion: pred->elem <= pred->next->elem <= pred->next->next->elem
pred->next->next
![Page 60: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/60.jpg)
Assertions for continued advancing
• 7-2 addedNode->elem > pred->next->elem
• 7-3 pred->next != 0
![Page 61: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/61.jpg)
Insert for Inorder List ADT• // cx7-9.cpp• // cx7-8.cpp• // implementation file, linked list implementation
of List ADT• #include "cx7-5.h"• void List::insert(const ListElementType & elem)• {• // precondition: list is in order• Link addedNode(new Node);
![Page 62: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/62.jpg)
Code Example 7-9• assert(addedNode);• addedNode->elem = elem;• // Special case: if existing list is empty, or if the new data• // is less than smallest item in the list, new node is added• // to the front of the list• if (head == 0 || elem <= head->elem) {• addedNode->next = head;• head = addedNode;• }• else {• // find the pointer to the node that is the predecessor• // to the new node in the in-order list
![Page 63: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/63.jpg)
Code Example 7-9• Link pred(head);• // assertion: pred->elem <= addedNode->elem• while (pred->next != 0 && pred->next->elem <= addedNode-
>elem)• // invariant: pred->next != 0 && pred->next->elem <= elem• pred = pred->next;• // assertion 7-1: (pred->elem <= addedNode->elem) &&• //(addedNode->elem <= pred->next->elem || pred->next == 0)• addedNode->next = pred->next;• pred->next = addedNode;• // assertion: pred->elem <= pred->next->elem &&• // (pred->next->elem <= pred->next->next->elem || pred-
>next->next == 0)• // postcondition: list is in order, with elem added
![Page 64: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/64.jpg)
Variations on linked lists• Dummy head nodes
– Eliminates special case surrounding first node in list
– Never insert or delete a first node• Circular linked lists• Doubly linked lists
![Page 65: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/65.jpg)
Empty linked lists
(head == 0)
(dummy)
![Page 66: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/66.jpg)
List comparisons
(dummy)
7 4
7 4
![Page 67: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/67.jpg)
List classfor list with dummy node• class List {• // Use L to mean "this List"• public:• List(); • // Precondition: None• // Postcondition: L is an empty List• void insert(const ListElementType & elem); • // Precondition: None• // Postcondition: Lpost = Lpre with an instance of
elem added to Lpost
![Page 68: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/68.jpg)
List operations (first)• bool first(ListElementType & elem);• // Precondition: None• // Postcondition: If the list empty, none.
Otherwise, variable elem contains first item in L; the "next" item to be returned is the second in L.
• // Returns: true if and only if there is at least one element in L
![Page 69: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/69.jpg)
List operations (next, remove)
• bool next(ListElementType & elem);• // Precondition: The "first" operation has been called at
least once.• // Postcondition: elem contains next item in L, if there is
one, and next counter advances by one; if no next element,none.
• // Returns: true if and only if there was a next item.• void remove(const ListElementType & target);• // Precondition: None• // Postcondition: Lpost = Lpre with one instance of target
removed
![Page 70: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/70.jpg)
Data members• private:• struct Node; // declaration without definition• typedef Node *Link; // use declaration of Node• struct Node { // now we define Node• ListElementType elem;• Link next;• };• Link head;• Link current;• };
![Page 71: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/71.jpg)
Modifications (constructor)• // cx7-11.cpp• #include "cx7-10.h"
• List::List()• {• // Initialize an empty list• head = new Node;• assert(head); // What is the reason for this?• head->next = 0;• current = 0;• }
![Page 72: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/72.jpg)
Modification to insert()• void List::insert(const ListElementType & elem)• { // precondition: list is in order• Link addedNode(new Node);• assert(addedNode);• addedNode->elem = elem;• // find pointer to predecessor in the in-order list• Link pred(head);• // loop invariant: pred>elem <= elem• while (pred->next != 0 && (pred->next->elem <=
addedNode->elem))• pred = pred->next;
![Page 73: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/73.jpg)
Insertion (con’t)• // assertion: (pred>elem <= addedNode>elem) &&• //(addedNode->elem <= pred->next->elem • // || pred->next == 0)• addedNode->next = pred->next;• pred->next = addedNode;• // postcondition: list is in order• }
![Page 74: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/74.jpg)
Modification of first• bool List::first(ListElementType &elem)• { // After first(), current points to first item in list• assert(head); // if no head, something is wrong! • if (head->next == 0)• return false;• else {• current = head->next;• elem = current->elem;• return true;• }• }
![Page 75: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/75.jpg)
Modification of next()• bool List::next(ListElementType & elem)• { // With proper use, current should be nonzero• assert(current);• // After each call, current points to item returned.• if (current->next == 0)• return false; // no next element available• else {• current = current->next;• elem = current->elem;• return true;• }• }
![Page 76: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/76.jpg)
Modification of remove()• void List::remove(const ListElementType & target)• { assert(head);• Link pred, delNode;• // pred starts out pointing at the dummy head• for (pred = head; pred->next != 0 && pred->next->elem <
target;pred = pred->next);• // at this point, check to see if we've found target --• // if so, remove it. Check to avoid dereferencing null pointer!• if (pred && (pred->next) && (pred->next->elem == target))
{ // remove the next node in the list• delNode = pred->next;• pred->next = delNode->next;• delete delNode; // return node to memory}• }
![Page 77: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/77.jpg)
List before removal
7 12
9pred
delNode
![Page 78: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/78.jpg)
List after removal
7 12
9pred
delNode
![Page 79: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/79.jpg)
Circular linked lists• No ‘0’ pointer at end• Last link points to first node• If external pointer is assigned to tail
of list, it is easy to reference both the tail and the head
![Page 80: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/80.jpg)
Circular linked list
7 12 5
![Page 81: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/81.jpg)
Doubly linked lists• Allow traversal in either direction• Require two links for each node
– Next– Predecessor
![Page 82: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/82.jpg)
A doubly linked list
7 12 5
head
![Page 83: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/83.jpg)
Header file for doubly linked list
• typedef int ListElementType;• class List {• public:• List();• void insert(const ListElementType & elem); • bool first(ListElementType & elem);• bool next(ListElementType & elem);• bool previous(ListElementType & elem);
![Page 84: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/84.jpg)
Data members• private:• struct Node; // declaration without definition• typedef Node *Link;• struct Node {• ListElementType elem;• Link next;• Link prev;• };• Link head;• Link current;• };
![Page 85: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/85.jpg)
Insertion into DLL (front)• void List::insert(const ListElementType & elem)• { Link addedNode = new Node;• assert(addedNode);• addedNode->elem = elem;• addedNode->next = head;• if (head) // test to see if a node exists• head->prev = addedNode; // if so, it needs to
point back to the new node• addedNode->prev = 0;• head = addedNode;• }
![Page 86: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/86.jpg)
Previous for DLL• bool List::previous(ListElementType &elem)• {• assert(current); • if (current->prev == 0)• return false;• else {• current = current->prev;• elem = current->elem;• return true;• }• }
![Page 87: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/87.jpg)
Dynamic Linear Lists• Arrays (conventional linear lists) are
dimensioned in the program code and space allocated at compile time.
• Dynamic arrays (dynamic linear lists) have space allocated for them at run-time.
• This makes them more versatile than static linear lists and easier to code than linked lists.
![Page 88: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/88.jpg)
Dynamic linear list class• typedef int ListElementType;• class List {• public:• List(int lSize);• void insert(const ListElementType & elem);• bool first(ListElementType & elem);• bool next(ListElementType & elem);• int size(); • private:• ListElementType * listArray;• int numberOfElements;• int currentPosition;• int listSize;• };
![Page 89: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/89.jpg)
Constructor and size accessor
• List::List(int lSize)• {• assert(lSize > 0);• listSize = lSize;• listArray = new ListElementType[listSize];• assert(listArray); // memory was successfully allocated• numberOfElements = 0;• currentPosition = -1;• }• List::size()• {• return listSize;• }
![Page 90: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/90.jpg)
Dynamic list client• int main()• {• int list1size, list2size;• cout << "Enter size of the first list: ";• cin >> list1size;• List list1(list1size);• cout << "Enter size of the second list: ";• cin >> list2size;• List list2(list2size);• // . . . and so on . . .• }
![Page 91: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/91.jpg)
The use of const• If a const could possibly be passed to a
function, then the function must be able to accept it.
• Const is generally the proper way to implement accessors
• It avoid client code blowing up when it sends a const actual argument into a function with non-const formal arguments
![Page 92: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/92.jpg)
Example of use of const• #include <string>• class ClubMember {• public:• ClubMember();• void setName(const string & fn, const string & ln);• void setAddress(const string & ad1, const string & ad2);• void setTelnum(const string & tn); • void setGradYear(const int gy);• void setClubMemberData(const string & fn, const string & ln, const string & ad1,
const string & ad2, const string & tn, const int gy);• string getFirstName() const;• string getLastName() const;• string getAddrOne() const;• string getAddrTwo() const;• string getTelnum() const;• int getGradYear() const;
![Page 93: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/93.jpg)
Private section of class• private:• string firstName;• string lastName;• string addrOne;• string addrTwo;• string telNum;• int gradYear;• };
![Page 94: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/94.jpg)
Const problem situation• Void printMember(const ClubMember &member)• {• cout << member.GetFirstName()
• If GetFirstName is not const the compiler will assume it may change any involved parameters and disallow this for a printMember where the parameter was const.
• string getFirstName() const; // is OK• string getFirstName(); // is dangerous
![Page 95: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/95.jpg)
Operator overloading• This is important when using class
objects (derived types)• Standard operators are designed
only to work with native types.• If you invent a class and intend to
use operators, you must overload them for your class objects.
![Page 96: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/96.jpg)
<= operator overloading• // We'll use the names lhs -- short for left hand side -- as the• // name for the argument on the left of an operator, • // and rhs -- right hand side -- for the argument on the right.
• int operator<= (const ClubMember & lhs, const ClubMember & rhs)
• {• if (lhs.getLastName() == rhs.getLastName())• return lhs.getFirstName() <= rhs.getFirstName();• else• return lhs.getLastName() <= rhs.getLastName();• }
![Page 97: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/97.jpg)
Chapter Summary• A List ADT represents items that can be retrieved in
some order.• Linear lists implement the List ADT using an array.• Iterator functions can be used to retrieve items in a
List.• Linked list provide greater flexibility by breaking
the connection between the logical idea of a list and its implementations.
• Dynamic memory allocation allows a program to allocate memory at runtime.
![Page 98: Chapter 7: The List ADT](https://reader035.fdocuments.in/reader035/viewer/2022062310/56816799550346895ddcd739/html5/thumbnails/98.jpg)
Chapter Summary• The Inorder List ADT maintains items in a specified
order.• Dummy head-nodes, circular linked lists, and
doubly-linked lists provide alternative approaches to the implementation of a linked list.
• Client applications may need to implement particular functions for classes stored within another class.
• Operator overloading provides a way to make built-in operators meaningful for user-defined classes.