W9 Linked List
W9 Linked List
Programming
                                         3
Why Learning Linked List?
                                                                      4
Introduction to Linked List
                                                                     5
Introduction to Linked List
Deleting a node
                                                                  6
An Empty Linked List
     Make nullptr your default choice for representing null pointers in C++
                                                                              7
Define a Linked List
• Declare a node:
      struct Node
      {
          double value; //It can be other data types
          Node *next;
 };
  No memory is allocated at this time
• Define a pointer to be used as the list head and initialize it to
  nullptr
      Node* head = nullptr;
                                                                      8
Outline
                                         9
Two Common Pointer Bugs in
implementing linked list operations
• Attempting to dereference a pointer via *p or p-> when
  p==NULL or p == nullptr
• Attempting to dereference a pointer via *p or p-> when p is
  not properly initialized
• NOTE: this error does not cause a syntax error, but instead
  causes errors:
  - Bus Error
  - Segmentation violation
  - Address protection violation
                                                                10
Add a Node at the End of the List
• Basic process:
   – Create the new node
   – Add node to the end of the list:
       • If list is empty, set head pointer to this node
       • Else,
            – traverse the list to the end
            – set pointer of last node to point to new node
• It is the basic operation for creating a linked list
                                                              11
Create a New Node
                                         Node
• Allocate memory for the new node:
    Node = new Node;
• Initialize the contents of the node:
      Node->value = num;                 Node
      Node->next = nullptr;
                                         Node
                                                num   nullptr
                                                                12
     Add a Node at the End of the List
#include <iostream>
using namespace std;
struct Node {
 double value; // Can be any data type
 Node* next;                                                    12.5
};
int main() {
  Node* head = nullptr; // Create the head pointer
  insertNode2ListEnd (head, 12.5);
  insertNode2ListEnd (head, 13.5);
  cout<<"1st Node: "<< head->value <<endl;
  cout<<"2nd Node: "<< head->next->value<<endl;
  return 0;
}                                                                                     13
     Add a Node at the End of the List
#include <iostream>
using namespace std;
struct Node {
 double value; // Can be any data type
 Node* next;                                                      12.5
};
int main() {
  Node* head = nullptr; // Create the head pointer
  insertNode2ListEnd (head, 12.5);
  insertNode2ListEnd (head, 13.5);
  cout<<"1st Node: "<< head->value <<endl;
  cout<<"2nd Node: "<< head->next->value<<endl;
  return 0;
}                                                                                     14
A Reference to Pointer
• Node*& head vs. Node* head
  - A reference to a pointer: Node*& head
 - A regular pointer: Node* head
• A reference to a pointer can ensure that any modifications to
  head within the function can affect the original linked list
                                                                  15
     A Reference to Pointer vs a Regular
     Pointer
#include <iostream>
using namespace std;
void modifyPointer(int* p) {
  int x = 10;
  p = &x; // This only modifies the local copy of pointer p, not the original pointer p in main
}
                                                                                                          Program output:
int main() {
  int a = 5;                                                                                      Before modifyPointer: 5
  int* ptr = &a;                                                                                  After modifyPointer: 5
                                      a
     Addr: 9000                        5                               Need to use a reference to pointer to change
                                                                         the content of the original pointer here!
                                      ptr
                                                                                                    x
     Addr: 7000                    9000                                            Addr: 5000
                                                                                                    10
                                      p
     Addr: 6000                    9000                                                                                     16
     A Reference to Pointer vs a Regular
     Pointer
#include <iostream>
using namespace std;
void modifyPointer(int* p) {
  int x = 10;
  p = &x; // This only modifies the local copy of pointer p, not the original pointer p in main
}
                                                                                                          Program output:
int main() {
  int a = 5;                                                                                      Before modifyPointer: 5
  int* ptr = &a;                                                                                  After modifyPointer: 5
                                      a
     Addr: 9000                        5                               Need to use a reference to pointer to change
                                                                         the content of the original pointer here!
                                      ptr
                                                                                                    x
     Addr: 7000                    9000                                            Addr: 5000
                                                                                                    10
                                      p
     Addr: 6000                    9000                                                                                     17
Delete a Node
                                                                 18
  Delete a Node
                                    void remove(Node*& head, double number) {
• Basic process:                     Node *nodePtr, *previousNodePtr;
   - Locating the node containing       if (head == nullptr) return; // If the list is empty
                                        // Determine if the first node is the one to delete
the element to be removed               if (fabs(head->value - number) < 1e-9)
                                        {
   - Unhooking the node from               nodePtr = head;
                                           head = head->next;
the list                                   delete nodePtr;
                                           nodePtr = nullptr;
   - Deleting the memory                } else
                                        { // Initialize nodePtr to the list head
allocated to the node                      nodePtr = head;
                                    // Link the previous node to the node after nodePtr, then delete nodePtr.
                                       if (nodePtr != nullptr)
                                       {
                                                previousNodePtr->next = nodePtr->next;
                                                delete nodePtr;
                                                nodePtr = nullptr;
                                            }
                                        }
                                    }
                                                                                                                19
  Delete a Node
                   void remove(Node*& head, double number) {
• Basic process:    Node *nodePtr, *previousNodePtr;
                   // Link the previous node to the node after nodePtr, then delete nodePtr.
                      if (nodePtr != nullptr)
                      {
                               previousNodePtr->next = nodePtr->next;
                               delete nodePtr;
                               nodePtr = nullptr;
                           }
                       }
                   }
                                                                                               20
  Delete a Node
                   void remove(Node*& head, double number) {
• Basic process:    Node *nodePtr, *previousNodePtr;
                   // Link the previous node to the node after nodePtr, then delete nodePtr.
                      if (nodePtr != nullptr)
                      {
                               previousNodePtr->next = nodePtr->next;
                               delete nodePtr;
                               nodePtr = nullptr;
                           }
                       }
                   }
                                                                                               21
  Delete a Node
                   void remove(Node*& head, double number) {
• Basic process:    Node *nodePtr, *previousNodePtr;
                   // Link the previous node to the node after nodePtr, then delete nodePtr.
                      if (nodePtr != nullptr)
                      {
                               previousNodePtr->next = nodePtr->next;
                               delete nodePtr;
                               nodePtr = nullptr;
                           }
                       }
                   }
                                                                                               22
  Delete a Node
                   void remove(Node*& head, double number) {
• Basic process:    Node *nodePtr, *previousNodePtr;
                   // Link the previous node to the node after nodePtr, then delete nodePtr.
                      if (nodePtr != nullptr)
                      {
                               previousNodePtr->next = nodePtr->next;
                               delete nodePtr;
                               nodePtr = nullptr;
                           }
                       }
                   }
                                                                                               23
  Delete a Node
                   void remove(Node*& head, double number) {
• Basic process:    Node *nodePtr, *previousNodePtr;
                   // Link the previous node to the node after nodePtr, then delete nodePtr.
                      if (nodePtr != nullptr)
                      {
                               previousNodePtr->next = nodePtr->next;
                               delete nodePtr;
                               nodePtr = nullptr;
                           }
                       }
                   }
                                                                                               24
Outline
                                         25
  Traverse 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 nullptr
       • process data
       • go to the next node by setting the pointer to the pointer field of the
         current node in the list
   – end while
       nodePtr points to the node containing 2.5, then the node containing 7.9,
       then the node containing 12.6, then points to nullptr, and the list
       traversal stops
                                                                                  26
  Traverse a Linked List
• Example: printList()
• Basic process:
   – set a pointer to the contents of the head pointer
   – while pointer is not nullptr
       • process data
       • go to the next node by setting the pointer to the pointer field of the
         current node in the list
   – end while
                                                                                  27
Traverse a Linked List
 void printList(Node* head) {
     Node* current = head;// Start at the head of the list
Program output:
                                                                                28
Traverse a Linked List
 void printList(Node* head) {
     Node* current = head;// Start at the head of the list
Program output:
2.5 ->
                                                                                29
Traverse a Linked List
 void printList(Node* head) {
     Node* current = head;// Start at the head of the list
Program output:
2.5 ->
                                                                                30
Traverse a Linked List
 void printList(Node* head) {
     Node* current = head;// Start at the head of the list
Program output:
2.5 ->
                                                                                      31
Traverse a Linked List
 void printList(Node* head) {
     Node* current = head;// Start at the head of the list
Program output:
2.5 ->
                                                                                           32
  Delete/Destroy a Linked List
• The nodes of a linked list are dynamically allocated
• When deleting or destroying a linked list, we must remove all
  nodes used in the list, where we need to traverse the linked list
• Basic process:
   – set a pointer nodePtr to the contents of the head pointer
   – while pointer is not nullptr
       • use another pointer garbage to keep track of the node to be deleted
       • go to the next node by setting the pointer nodePtr to the pointer field
         of the current node in the list
       • deallocate the memory of the current node
   – end while
                                                                                   33
  Delete/Destroy a Linked List
• Basic process:
   – set a pointer nodePtr to the contents of the head pointer
   – while pointer is not nullptr
       • use another pointer garbage to keep track of the node to be deleted
       • go to the next node by setting the pointer nodePtr to the pointer field
         of the current node in the list
       • deallocate the memory of the current node
   – end while
nodePtr
                                                          35
Delete/Destroy a Linked List
     void destroyList(Node*& head)
     {
         Node *nodePtr = head; // Start at head of list
         Node *garbage = nullptr;
         while (nodePtr != nullptr)
         {
           // garbage keeps track of node to be deleted
           garbage = nodePtr;
           // Move on to the next node, if any
           nodePtr = nodePtr->next;
           // Delete the "garbage" node
             delete garbage;
             garbage = nullptr;
         }
         head = nullptr;
     }
nodePtr
                      garbage
                                                          36
Delete/Destroy a Linked List
     void destroyList(Node*& head)
     {
         Node *nodePtr = head; // Start at head of list
         Node *garbage = nullptr;
         while (nodePtr != nullptr)
         {
           // garbage keeps track of node to be deleted
           garbage = nodePtr;
           // Move on to the next node, if any
           nodePtr = nodePtr->next;
           // Delete the "garbage" node
             delete garbage;
             garbage = nullptr;
         }
         head = nullptr;
     }
                                           nodePtr
                      garbage
                                                          37
Delete/Destroy a Linked List
     void destroyList(Node*& head)
     {
         Node *nodePtr = head; // Start at head of list
         Node *garbage = nullptr;
         while (nodePtr != nullptr)
         {
           // garbage keeps track of node to be deleted
           garbage = nodePtr;
           // Move on to the next node, if any
           nodePtr = nodePtr->next;
           // Delete the "garbage" node
             delete garbage;
             garbage = nullptr;
         }
         head = nullptr;
     }
                                           nodePtr
                      garbage
                                                          38
Delete/Destroy a Linked List
     void destroyList(Node*& head)
     {
         Node *nodePtr = head; // Start at head of list
         Node *garbage = nullptr;
         while (nodePtr != nullptr)
         {
           // garbage keeps track of node to be deleted
           garbage = nodePtr;
           // Move on to the next node, if any
           nodePtr = nodePtr->next;
           // Delete the "garbage" node
             delete garbage;
             garbage = nullptr;
         }
         head = nullptr;
     }
                                           nodePtr
                                           garbage
                                                          39
Delete/Destroy a Linked List
     void destroyList(Node*& head)
     {
         Node *nodePtr = head; // Start at head of list
         Node *garbage = nullptr;
         while (nodePtr != nullptr)
         {
           // garbage keeps track of node to be deleted
           garbage = nodePtr;
           // Move on to the next node, if any
           nodePtr = nodePtr->next;
           // Delete the "garbage" node
             delete garbage;
             garbage = nullptr;
         }
         head = nullptr;
     }
                                                          nodePtr
                                           garbage
                                                                    40
Delete/Destroy a Linked List
     void destroyList(Node*& head)
     {
         Node *nodePtr = head; // Start at head of list
         Node *garbage = nullptr;
         while (nodePtr != nullptr)
         {
           // garbage keeps track of node to be deleted
           garbage = nodePtr;
           // Move on to the next node, if any
           nodePtr = nodePtr->next;
           // Delete the "garbage" node
             delete garbage;
             garbage = nullptr;
         }
         head = nullptr;
     }
                                                          nodePtr
                                           garbage
                                                                    41
Delete/Destroy a Linked List
     void destroyList(Node*& head)
     {
         Node *nodePtr = head; // Start at head of list
         Node *garbage = nullptr;
         while (nodePtr != nullptr)
         {
           // garbage keeps track of node to be deleted
           garbage = nodePtr;
           // Move on to the next node, if any
           nodePtr = nodePtr->next;
           // Delete the "garbage" node
             delete garbage;
             garbage = nullptr;
         }
         head = nullptr;
     }
                                                          nodePtr
                                                          garbage
                                                                    42
Delete/Destroy a Linked List
     void destroyList(Node*& head)
     {
         Node *nodePtr = head; // Start at head of list
         Node *garbage = nullptr;
         while (nodePtr != nullptr)
         {
           // garbage keeps track of node to be deleted
           garbage = nodePtr;
           // Move on to the next node, if any
           nodePtr = nodePtr->next;
           // Delete the "garbage" node
             delete garbage;
             garbage = nullptr;
         }
         head = nullptr;
     }
nodePtr
                                                          garbage
                                                                              43
Delete/Destroy a Linked List
     void destroyList(Node*& head)
     {
         Node *nodePtr = head; // Start at head of list
         Node *garbage = nullptr;
         while (nodePtr != nullptr)
         {
           // garbage keeps track of node to be deleted
           garbage = nodePtr;
           // Move on to the next node, if any
           nodePtr = nodePtr->next;
           // Delete the "garbage" node
             delete garbage;
             garbage = nullptr;
         }
         head = nullptr;
     }
nodePtr
                                                          garbage
                                                                              44
Delete/Destroy a Linked List
     void destroyList(Node*& head)
     {
         Node *nodePtr = head; // Start at head of list
         Node *garbage = nullptr;
         while (nodePtr != nullptr)
         {
           // garbage keeps track of node to be deleted
           garbage = nodePtr;
           // Move on to the next node, if any
           nodePtr = nodePtr->next;
           // Delete the "garbage" node
             delete garbage;
             garbage = nullptr;
         }
         head = nullptr;
     }
nodePtr
                                                                    garbage
                                                                              45
Outline
                                         46
Variations of the Linked List
• There are many ways to link dynamically allocated data
  structures together. Two variations of the linked list are the
  doubly linked list and the circular linked list.
 The last node and first node have pointers to the NULL address, which
 can be used to check if we have reached either end.
Variations of the Linked List
• Circular linked list: The last node in this type of linked list
  points to the first node, not to the NULL address
More about Linked List
• There are other linked list operations, e.g., list copy, list
  append, compute the length of a linked list, etc., but the basic
  ideas are more or less the same
                                        50
Questions?
Thank You!