Differences in passing the head variable in C and Java

  • Due to the fact that Java is an Object Oriented programming language:

    • The head variable is stored inside the List class
    • List manipulation methods access this variable as: this.head

    Example:

     public class List
     {
         private Node head;
    
         public void insert( ... ) { this.head...  }
         public void remove( ... ) { this.head...  }
         ...
    }
    

  • The head variable is passed to the methods as the implicit parameter:

      List myList = new List();
    
      myList.insert( ... );  // Uses myList.head as: this.head
    

Differences in passing the head variable in C and Java

  • Due to the fact that C is not an Object Oriented programming language:

    • The head variable and the (insert/remove) methods that manipulate the linked list are stored separately

    • We must pass the head variable as a parameter to the list manipulation functions

      (It will be passed by value !)

    • Therefore, the list manipulation functions must return the new head value (so we can update the head variable

    Example:

     
    
     int main( )
     {
        
        
     }
    

Differences in passing the head variable in C and Java

  • Due to the fact that C is not an Object Oriented programming language:

    • The head variable and the (insert/remove) methods that manipulate the linked list are stored separately

    • We must pass the head variable as a parameter to the list manipulation functions

      (It will be passed by value !)

    • Therefore, the list manipulation functions must return the new head value (so we can update the head variable

    Example: the head variable is not accessible by the list manipulation functions

                  insert(              , ... ) { ...  cannot access head     }
    
     int main( )
     {
        struct Node *head;
     
     }
    

Differences in passing the head variable in C and Java

  • Due to the fact that C is not an Object Oriented programming language:

    • The head variable and the (insert/remove) methods that manipulate the linked list are stored separately

    • We must pass the head variable as a parameter to the list manipulation functions

      (It will be passed by value !)

    • Therefore, the list manipulation functions must return the new head value (so we can update the head variable

    Example: we must pass head as a parameter to the list manipulation function

                  insert(struct Node *h, ... ) { ...                         }
    
     int main( )
     {
        struct Node *head;          // Sometimes, we need to update the head var !
               insert(head, .... ); // head is passed by value -- problem...
     }
    

Differences in passing the head variable in C and Java

  • Due to the fact that C is not an Object Oriented programming language:

    • The head variable and the (insert/remove) methods that manipulate the linked list are stored separately

    • We must pass the head variable as a parameter to the list manipulation functions

      (It will be passed by value !)

    • Therefore, the list manipulation functions must return the new head value (so we can update the head variable

    Example: we must return a updated head value so we can update the head variable

     struct Node *insert(struct Node *h, ... ) { ...  return new head value; }
    
     int main( )
     {
        struct Node *head;
        head = insert(head, .... );  // Only way to update head !
     }
    

List processing algorithms

  • Recall that:

    • The program uses the first (or head) variable to reference to the first node of a linked list

    • Only the first node is immediately accessible by the program

  • Processing data stored in a linked list (a.k.a. list processing) often requires:

    • visiting all elements in the linked list by traversing the chain

    Graphically:

The standard list traversal algorithm

  • Warning: you must never use the variable first to traverse the linked list:
     

       // The standard list traversal algorithm
    
       Node p;
    
       p = first;
    
       while ( p != NULL )
       {
           // Process data in node p
    
           p = p->next;
       }
    

The standard list traversal algorithm

  • Define a helper reference variable p to traverse the linked list:
     

       // The standard list traversal algorithm
    
       struct Node *p;
    
       p = first;
    
       while ( p != NULL )
       {
           // Process data in node p
    
           p = p->next;
       }
    

The standard list traversal algorithm

  • Initialize the helper reference variable p to point the first node of the linked list:

       // The standard list traversal algorithm
    
       struct Node *p;
    
       p = first;   // P now points to the first node
    
       while ( p != NULL )
       {
           // Process data in node p
    
           p = p->next;
       }
    

The standard list traversal algorithm

  • When p is pointing at a certain node, we can access its data as p->item:
     

       // The standard list traversal algorithm
    
       struct Node *p;
    
       p = first;   // P now points to the first node
    
       while ( p != NULL )
       {
           Notice:  p->item/value is the data stored in node
    
           Notice:  p->next is the address of the next Node !
       }
    

The standard list traversal algorithm

  • After processing a node, we advance p to point to the next node with the statement   p = p->next:

       // The standard list traversal algorithm
    
       struct Node *p;
    
       p = first;   // P now points to the first node
    
       while ( p != NULL )
       {
          
    
           p = p->next; // Advances p to next node
       }
    

The standard list traversal algorithm

  • Insight: the reason why the variable p "advances" to the next node is because
    p = p->next assigns the address in p->next to the variable p:

       // The standard list traversal algorithm
    
       struct Node *p;
    
       p = first;   // P now points to the first node
    
       while ( p != NULL )
       {
           
    
           p = p->next; // Advances p to next node
       }
    

The standard list traversal algorithm

  • We repeat the steps until we have process the data in the last node, then p will contain NULL:

       // The standard list traversal algorithm
    
       struct Node *p;
    
       p = first;   // P now points to the first node
    
       while ( p != NULL )
       {
           // Process data (p->item/value) in node p
    
           p = p->next; // Advances p to next node
       }
    

Animation of the standard list traversal algorithm

  • The helper variable is often called current (because it points to the current node that is being processed):

    The list traversal algorithm re-written with the current variable:

       struct Node *current = first;
    
       while ( current != NULL ) // Find last list element
       {
           // Process current node here
    
           current = current->next;  // Move to next node
       }
    
    

Use the list traversal algorithm to print out all items in a list

  • Problem:   write a program fragment that

    • Print out all the item values stored in a linked list

  • The list traversal algorithm will visit every node p:

       // The standard list traversal algorithm
    
       struct Node *p;
    
       p = first;   // P now points to the first node
    
       while ( p != NULL )
       {
           // Visiting node p (p->item = data store in p)
    
           p = p->next; // Advances p to next node
       }
    

     

Use the list traversal algorithm to print out all items in a list

  • Problem:   write a program fragment that

    • Print out all the item values stored in a linked list

  • To print out all data item stored in a linked list:

       // The standard list traversal algorithm
    
       struct Node *p;
    
       p = first;   // P now points to the first node
    
       while ( p != NULL )
       {
           printf("%d " p->item );
    
           p = p->next; // Advances p to next node
       }
    

    Print out the value in item using p->item during the list traversal...

DEMO: demo/C/Linked-list/traverse.c

Enhancements of the list traversal algorithm

  • The list traversal algorithm is the basis for other list processing algorithms.

    Example:

    • Find a node in the list that contains a special value (say: X).

  • Here is the basic list traversal algorithm:

       struct Node *current = first;
    
       while ( current != NULL )
       {
           // Process current node here
    
    
           current = current->next;  // Move to next node
       }
    
    
    
    
    

Enhancements of the list traversal algorithm

  • The list traversal algorithm is the basis for other list processing algorithms.

    Example:

    • Find a node in the list that contains a special value (say: X).

  • To find a node that contains X, we exit the loop when the current contains the X:

       struct Node *current = first;
    
       while ( current != NULL ) // Find list element containing X
       {
           if ( current (node) contains X )
               break;
    
           current = current->next;  // Move to next node
       }
    
       // Here:
       //    either current == NULL (no node contains X)
       //    or the current (node) contains X
    

Enhancements of the list traversal algorithm

  • The list traversal algorithm is the basis for other list processing algorithms.

    Example:

    • Find a node in the list that contains a special value (say: X).

  • The search adaptation of the list traversal is often written as follows:

       struct Node *current = first;
    
       while ( current != NULL && !(current (node) contains X) ) 
       {
        
              
    
           current = current->next;  // Move to next node
       }
    
       // Here:
       //    either current == NULL (no node contains X)
       //    or the current (node) contains X
    

Use the list traversal algorithm to find a list element that contains a certain key

  • Problem:

    • Write a method that returns a list element that contains a certain value

  • The method findNode(f, s) finds a node in linked list f that contains the value s:

       struct Node *findNode( struct Node *f, int s )
       {
           struct Node *p = first;
    
           while ( p != NULL )
           {
               // Visiting node p (p->item = data store in p)
    
    
               p = p->next; // Advances p to next node
           }
    
           return NULL;
       }
    

Use the list traversal algorithm to find a list element that contains a certain key

  • Problem:

    • Write a method that returns a list element that contains a certain value

  • We test every node by (1) visit the node (using the variable p):

       struct Node *findNode( struct Node *f, int s )
       {
           struct Node *p = f;            // Start at the first node f
    
           while ( p != NULL )    // Visit every node in list f
           {
               // Visiting node p (p->item = data store in p)
    
    
               p = p->next; // Advances p to next node
           }
    
           return NULL;
       }
    

Use the list traversal algorithm to find a list element that contains a certain key

  • Problem:

    • Write a method that returns a list element that contains a certain value

  • (2) If node p contains the search value, we return p:

       struct Node *findNode( struct Node *f, int s )
       {
           struct Node *p = f;            // Start at the first node f
    
           while ( p != NULL )    // Visit every node in list f
           {
               if ( p->item == s )
                   return p;      // Found s --> return p
    
               p = p->next; // Advances p to next node
           }
    
           What to do if not found???
       }
    

Use the list traversal algorithm to find a list element that contains a certain key

  • Problem:

    • Write a method that returns a list element that contains a certain value

  • (3) If we exit the loop, then s is not found in the linked list f --- we return NULL:

       struct Node *findNode( struct Node *f, int s )
       {
           struct Node *p = f;            // Start at the first node f
    
           while ( p != NULL )    // Visit every node in list f
           {
               if ( p->item == s )
                   return p;      // Found s --> return p
    
               p = p->next; // Advances p to next node
           }
    
           return NULL;           // Not found
       }
    

DEMO: demo/C/Linked-list/findNode.c