590 likes | 608 Views
Learn the basics of linked lists, a sequence of data structures with each node containing a pointer to its successor. Explore the terminology, operations, and implementations of linked lists in C++.
E N D
Chapter 17: Linked Lists Starting Out with C++ Early Objects Seventh Edition by Tony Gaddis, Judy Walters, and Godfrey Muganda
17.1 Introduction to the Linked List ADT NULL list head 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
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.
Linked Lists list head NULL Add or delete node 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
Linked Lists vs. Arrays and Vectors NULL list head 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
Node Organization pointer data A node contains: • data: one or more data fields – may be organized as structure, object, etc. • a pointer that can point to another node
list head NULL Empty List A list with no nodes is called the empty list In this case the list head is set to NULL
C++ Implementation Implementation of nodes requires a structure containing a pointer to a structure of the same type: struct ListNode { int data; ListNode *next; };
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 << "First item is " << head->value << endl; cout << "Second item is " << head->next->value << endl; return 0; }
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.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
Creating an Empty List head NULL • Define a pointer for the head of the list: ListNode *head = NULL; • Head pointer initialized to NULL to indicate an empty list
CIS 15 Linked Lists 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
NULL 23 Creating a Node p ListNode *p; int num = 23; p=new ListNode(num);
CIS 15 Linked Lists newNode newNode 23 newNode NULL 23 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;
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 << ptr->value << " "; // Process node ptr = ptr->next; // Move to next node } return 0; }
A ----------------- 10 ----------------- NULL node address ----------------------- value ------------------------ next numberList B ----------------- 20 ----------------- A A ----------------- 10 ----------------- NULL numberList C ----------------- 30 ----------------- B B ----------------- 20 ----------------- A A ----------------- 10 ----------------- NULL numberList D ----------------- 40 ----------------- C C ----------------- 30 ----------------- B B ----------------- 20 ----------------- A A ----------------- 10 ----------------- NULL numberList
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);
p Appending an Item 5 13 23 NULL list head List originally has 5, 13. p locates the last node, then a node with a new item, 23, is added
CIS 15 Linked Lists nodePtr 5 13 19 NULL list head 23 NULL newNode Appending a Node New node created, end of list located
CIS 15 Linked Lists nodePtr 5 13 19 list head 23 NULL newNode Appending a Node New node added to end of list
//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(); };
//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); } }
//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 << nodePtr->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 } }
//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; }
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
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
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
Inserting a Node into a Linked List previousNode nodePtr 5 13 19 NULL list head 17 NULL newNode Item to insert Correct position located
Inserting a Node into a Linked List previousNode nodePtr 5 13 19 NULL list head 17 New node created and inserted in order in the linked list
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
CIS 15 Linked Lists 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
Traversing a Linked List nodePtr 5 13 19 NULL list head nodePtr points to the node containing5, then the node containing 13, then the node containing 19, then points to NULL, and the list traversal stops
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
Deleting a Node Contents of node to be deleted: 13 previousNode nodePtr 5 13 19 NULL list head Locating the node containing 13
Deleting a Node previousNode nodePtr 5 13 19 NULL list head Adjusting pointer around the node to be deleted
Deleting a Node previousNode nodePtr 5 19 NULL list head Linked list after deleting the node containing 13
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.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.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
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