chapter 7: the list adt. chapter 7 –lists overview –the list adt and its uses; dynamic memory...

98
Chapter 7: The List ADT

Post on 19-Dec-2015

256 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

Chapter 7: The List ADT

Page 2: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

• Chapter 7– Lists

• Overview– The List ADT and its uses; dynamic

memory allocation; programming with linked lists.

Page 3: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

A useful exercise

• Define some additional operations that might be useful for a List ADT.

Page 8: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

List();

• Is the list copy constructor

• With no parameters or body it is a ‘default constructor’

Page 12: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

Insertion into linear list

• void List::insert(const ListElementType & elem)• {• assert(numberOfElements < maxListSize);• listArray[numberOfElements] = elem;• numberOfElements++; }

Page 18: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

Figure 7-2

7 12 5

Page 26: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

Figure 7-3

7 12 5

head

Page 27: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

Figure 7-4

7 12 5

9

head

Page 29: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

Figure 7-5

7 12 5

9

head

Page 30: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

Figure 7-6

7 12 5

9

headtail

Page 32: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

Figure 7-7

7 12 5

9

head

tail

Page 33: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

Linked list constructor

• List::List()• {• // Initialize an empty list• head = 0;• tail = 0;• current = 0;• }

Page 39: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

Linked list implementation

• List::List()• {• // Initialize an empty List• head = 0;• tail = 0;• current = 0;• }

Page 43: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

Figure 7-8

7 12 5

7 12 5

head

head

current

currentelem next

elem next

Page 47: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

Inorder invariant

u v

invariant: u < v

Page 54: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

Insertion (before)

7 12

9

Page 55: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

Insertion (after)

7 12

9

Page 56: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

Required insertion pointers

7 12

9predaddedNode

Page 57: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

Assertion (considering end-of-list)

• (pred->elem <= addedNode->elem) &&

• (addedNode->elem <= pred->next->elem || pred->next == 0).

Page 59: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

Assertions for continued advancing

• 7-2 addedNode->elem > pred->next->elem

• 7-3 pred->next != 0

Page 61: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

Empty linked lists

(head == 0)

(dummy)

Page 66: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

List comparisons

(dummy)

7 4

7 4

Page 67: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

List before removal

7 12

9pred

delNode

Page 78: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

List after removal

7 12

9pred

delNode

Page 79: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

Circular linked list

7 12 5

Page 81: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

Doubly linked lists

• Allow traversal in either direction

• Require two links for each node– Next– Predecessor

Page 82: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

A doubly linked list

7 12 5

head

Page 83: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

Private section of class

• private:• string firstName;• string lastName;• string addrOne;• string addrTwo;• string telNum;• int gradYear;• };

Page 94: Chapter 7: The List ADT. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

<= 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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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. Chapter 7 –Lists Overview –The List ADT and its uses; dynamic memory allocation; programming with linked lists

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.