Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Starting Out with C++ Early Objects Seventh Edition by Tony Gaddis, Judy Walters, and Godfrey Muganda Chapter 17: Linked Lists
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley 17.1 Introduction to the Linked List ADT Linked list: a sequence of data structures (nodes) with each node containing a pointer to its successor The last node in the list has its successor pointer set to NULL 17-2 NULL list head
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Linked List Terminology The node at the beginning is called the head of the list The entire list is identified by the pointer to the head node. This pointer is called the list head. 17-3
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Linked Lists Nodes can be added or removed from the linked list during execution Addition or removal of nodes can take place at beginning, end, or middle of the list 17-4 NULL list head Add or delete node
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Linked Lists vs. Arrays and Vectors Linked lists can grow and shrink as needed, unlike arrays, which have a fixed size Unlike vectors, insertion or removal of a node in the middle of the list is very efficient 17-5 NULL list head
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Node Organization A node contains: –data: one or more data fields – may be organized as structure, object, etc. –a pointer that can point to another node 17-6 data pointer
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Empty List A list with no nodes is called the empty list In this case the list head is set to NULL 17-7 NULL list head
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley C++ Implementation Implementation of nodes requires a structure containing a pointer to a structure of the same type: struct ListNode { int data; ListNode *next; }; 17-8
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley struct ListNode { double value; ListNode *next; }; int main() { ListNode *head; // Create first node with 12.5 head = new ListNode; // Allocate new node head->value = 12.5; // Store the value head->next = NULL; // Signify end of list // Create second node with 13.5 ListNode *secondPtr = new ListNode; secondPtr->value = 13.5; secondPtr->next = NULL; // Second node is end of list head->next = secondPtr; // First node points to second // Print the list. cout value << endl; cout next->value << endl; return 0; } 17-9
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley C++ Implementation Nodes can be equipped with constructors: struct ListNode { int data; ListNode *next; ListNode(int d, ListNode* p=NULL) {data = d; next = p;} }; 17-10
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley 17.2 Linked List Operations Basic operations: –add a node to the end of the list –insert a node within the list –traverse the linked list –delete a node –delete/destroy the list 17-11
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Creating an Empty List Define a pointer for the head of the list: ListNode *head = NULL; Head pointer initialized to NULL to indicate an empty list NULL head
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley CIS 15 Linked Lists 13 NULL Pointer Is used to indicate end-of-list Should always be tested for before using a pointer: ListNode *p; while (p != NULL)... Can also test the pointer itself: while (!p)... // same meaning // as above
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Creating a Node ListNode *p; int num = 23; p = new ListNode(num); NULL 23 p
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley CIS 15 Linked Lists 15 Creating a New Node Allocate memory for the new node: newNode = new ListNode; Initialize the contents of the node: newNode->value = num; Set the pointer field to NULL : newNode->next = NULL; newNode 23 NULL newNode 23
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley struct ListNode { double value; ListNode *next; ListNode(double value1, ListNode *next1 = NULL) { value = value1; next = next1; } }; int main() { ListNode *numberList = NULL; // List of numbers ifstream numberFile("numberFile.dat"); if (!numberFile) { cout << "Error in opening the file of numbers."; exit(1); } double number; cout << "The contents of the file are: " << endl; while (numberFile >> number) { cout << number << " "; numberList = new ListNode(number, numberList); } cout << endl << "The contents of the list are: " << endl; ListNode *ptr = numberList; while (ptr != NULL) { cout value << " "; // Process node ptr = ptr->next; // Move to next node } return 0; } 17-16
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley A NULL B A NULL B A NULL C B A NULL C B D C numberList node address value next node address value next
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Appending an Item To add an item to the end of the list: –If the list is empty, set head to a new node containing the item head = new ListNode(num); –If the list is not empty, move a pointer p to the last node, then add a new node containing the item p->next = new ListNode(num); 17-18
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Appending an Item list head p NULL List originally has 5, 13. p locates the last node, then a node with a new item, 23, is added
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley CIS 15 Linked Lists 20 Appending a Node NULL list head newNode 23 NULL nodePtr New node created, end of list located
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley CIS 15 Linked Lists 21 Appending a Node list head newNode 23 NULL nodePtr New node added to end of list
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley //NumberList.h class NumberList { protected: // Declare a class for the list node. struct ListNode { double value; ListNode *next; ListNode(double value1, ListNode *next1 = NULL) { value = value1; next = next1; } }; ListNode *head; // List head pointer public: NumberList() { head = NULL; } // Constructor ~NumberList(); // Destructor void add(double number); void remove(double number); void displayList(); }; 17-22
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley //NumberList.cpp #include "NumberList.h" using namespace std; //***************************************************** // add adds a new element to the end of the list. * //***************************************************** void NumberList::add(double number) { if (head == NULL) head = new ListNode(number); else { // The list is not empty. Use nodePtr to traverse the list ListNode *nodePtr = head; while (nodePtr->next != NULL) nodePtr = nodePtr->next; // nodePtr->next is NULL so nodePtr points to the last node. // Create a new node and put it after the last node. nodePtr->next = new ListNode(number); } 17-23
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley //NumberList.cpp // displayList outputs all values currently stored in the list. void NumberList::displayList() { ListNode *nodePtr = head; // Start at head of list while (nodePtr) { // Print the value in the current node cout value << " "; nodePtr = nodePtr->next; // Move on to the next node } // Destructor deallocates the memory used by the list. NumberList::~NumberList() { ListNode *nodePtr = head; // Start at head of list while (nodePtr != NULL) { // garbage keeps track of node to be deleted ListNode *garbage = nodePtr; nodePtr = nodePtr->next; // Move on to the next node, if any delete garbage; // Delete the "garbage" node } 17-24
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley //main.cpp // This program demonstrates the add and // display linked list operations. #include "Numberlist.h" using namespace std; int main() { NumberList list; list.add(2.5); list.add(7.9); list.add(12.6); list.displayList(); cout << endl; return 0; } 17-25
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Inserting a Node Used to insert an item into a sorted list, keeping the list sorted. Two possibilities: –Insertion is at the head of the list (because item at head is already greater than item being inserted, or because list is empty –Insertion is after an existing node in a non- empty list 17-26
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Inserting a Node in Body of a List Requires two pointers to traverse the list: –pointer to locate the node with data value greater than that of node to be inserted –pointer to 'trail behind' one node, to point to node before point of insertion New node is inserted between the nodes pointed at by these pointers 17-27
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Inserting a Node at Head of a List Test to see if –head pointer is null, or –node value pointed at by head is greater than value to be inserted Must test in this order: unpredictable results if second test is attempted on an empty list Create new node, set its next pointer to head, then point head to it 17-28
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Inserting a Node into a Linked List NULL list head nodePtrpreviousNode Correct position located Item to insert 17 NULL newNode
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Inserting a Node into a Linked List NULL list head nodePtrpreviousNode New node created and inserted in order in the linked list
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Traversing a Linked List List traversals visit each node in a linked list to display contents, validate data, etc. Basic process of traversal: set a pointer to the head pointer while pointer is not NULL process data set pointer to the successor of the current node end while 17-31
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley CIS 15 Linked Lists 32
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley CIS 15 Linked Lists 33
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley CIS 15 Linked Lists 34
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley CIS 15 Linked Lists 35 Traversing a Linked List Visit each node in a linked list: display contents, validate data, etc. Basic process: –set a pointer to the contents of the head pointer –while pointer is not NULL process data go to the next node by setting the pointer to the pointer field of the current node in the list –end while
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Traversing a Linked List NULL list head nodePtr nodePtr points to the node containing 5, then the node containing 13, then the node containing 19, then points to NULL, and the list traversal stops
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Removing an Element Used to remove a node from a linked list If list uses dynamic memory, then delete node from memory Requires two pointers: one to locate the node to be deleted, one to point to the node before the node to be deleted 17-37
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Deleting a Node NULL list head nodePtrpreviousNode Locating the node containing 13 Contents of node to be deleted: 13
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Deleting a Node NULL list head nodePtrpreviousNode Adjusting pointer around the node to be deleted
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Deleting a Node NULL list head 519 nodePtrpreviousNode Linked list after deleting the node containing 13
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley CIS 15 Linked Lists 41
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley CIS 15 Linked Lists 42
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley CIS 15 Linked Lists 43
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley CIS 15 Linked Lists 44
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley CIS 15 Linked Lists 45
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Destroying a Linked List Must remove all nodes used in the list To do this, use list traversal to visit each node For each node, –Unlink the node from the list –Free the node’s memory Finally, set the list head to NULL 17-46
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley CIS 15 Linked Lists 47
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley 17.3 A Linked List Template A linked list template can be written by replacing the type of the data in the node with a type parameter, say T. If defining the linked list as a class template, then all member functions must be function templates Implementation assumes use with data types that support comparison: == and <= project LinkedListTemplate 17-48
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley 17.4 Recursive Linked List Operations A non-empty linked list consists of a head node followed by the rest of the nodes The rest of the nodes form a linked list that is called the tail of the original list 17-49
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Recursive Linked List Operations Many linked list operations can be broken down into the smaller problems of processing the head of the list and then recursively operating on the tail of the list 17-50
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Recursive Linked List Operations To find the length (number of elements) of a list –If the list is empty, the length is 0 (base case) –If the list is not empty, find the length of the tail and then add 1 to obtain length of original list 17-51
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Recursive Linked List Operations To find the length of a list: int length(ListNode *myList) { if (myList == NULL) return 0; else return 1 + length(myList->next); } 17-52
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Other Recursive Linked List Operations General design considerations: Base case is often when the list is empty Recursive case often involves the use of the tail of the list (i.e., the list without the head). Since the tail has one fewer entry than the list that was passed in to this call, the recursion eventually stops. project LinkedListRecursive 17-53
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley 17.5 Variations of the Linked List Other linked list organizations: –doubly-linked list: each node contains two pointers: one to the next node in the list, one to the previous node in the list NULL list head NULL
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Variations of the Linked List Other linked list organizations: –circular linked list: the last node in the list points back to the first node in the list, not to NULL list head 51319
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley 17.6 The STL list Container Template for a doubly linked list Member functions for –locating beginning, end of list: front, back, end –adding elements to the list: insert, merge, push_back, push_front –removing elements from the list: erase, pop_back, pop_front, unique 17-56
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley 17-57
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley #include #include // Include the list header using namespace std; int main() { list myList; list ::iterator iter; // Add values to the list. for (int x = 0; x < 100; x += 10) myList.push_back(x); // Display the values. for (iter = myList.begin(); iter != myList.end(); iter++) cout << *iter << " "; cout << endl; myList.reverse(); //reverse the order of the elements. // Display the values again. for (iter = myList.begin(); iter != myList.end(); iter++) cout << *iter << " "; cout << endl; return 0; } 17-58
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Starting Out with C++ Early Objects Seventh Edition by Tony Gaddis, Judy Walters, and Godfrey Muganda Chapter 17: Linked Lists