The effect of removeLast() --- removing an item at the end of a linked list:
|
|
|
Let's implement the removeLast( ) method:
// Delete the node at the end of this list
struct Node *removeLast( )
{
// General case (take care of edge cases later)
struct Node *current = h;
struct Node *previous = h;
while( current->next != NULL ) // Find the last node
{
previous = current;
current = current->next; // Advance to next node
}
previous->next = NULL; // Unlink the last node (from its predecessor)
free(current); // De-allocate deleted node
return h; // Return (confirm first node was unchanged)
}
|
Start the search at the first node:
// Delete the node at the end of this list
struct Node *removeLast( )
{
// General case (take care of edge cases later)
struct Node *current = h;
struct Node *previous = h;
while( current->next != NULL ) // Find the last node
{
previous = current;
current = current->next; // Advance to next node
}
previous->next = NULL; // Unlink the last node (from its predecessor)
free(current); // De-allocate deleted node
return h; // Return (confirm first node was unchanged)
}
|
Find the last node while remembering its previous node:
// Delete the node at the end of this list
struct Node *removeLast( )
{
// General case (take care of edge cases later)
struct Node *current = h;
struct Node *previous = h;
while( current->next != NULL ) // Find the last node
{
previous = current;
current = current->next; // Advance to next node
}
previous->next = NULL; // Unlink the last node (from its predecessor)
free(current); // De-allocate deleted node
return h; // Return (confirm first node was unchanged)
}
|
Unlink the last node from the previous node:
// Delete the node at the end of this list
struct Node *removeLast( )
{
// General case (take care of edge cases later)
struct Node *current = h;
struct Node *previous = h;
while( current->next != NULL ) // Find the last node
{
previous = current;
current = current->next; // Advance to next node
}
previous->next = NULL; // Unlink the last node (from its predecessor)
free(current); // De-allocate deleted node
return h; // Return (confirm first node was unchanged)
}
|
De-allocate the deleted node:
// Delete the node at the end of this list struct Node *removeLast( ) { // General case (take care of edge cases later) struct Node *current = h; struct Node *previous = h; while( current->next != NULL ) // Find the last node { previous = current; current = current->next; // Advance to next node } previous->next = NULL; // Unlink the last node (from its predecessor) free(current); // De-allocate deleted node return h; // Return (confirm first node was unchanged) } |
Return the reference of the new first node: (in this case, we re-affirm h);
// Delete the node at the end of this list struct Node *removeLast( ) { // General case (take care of edge cases later) struct Node *current = h; struct Node *previous = h; while( current->next != NULL ) // Find the last node { previous = current; current = current->next; // Advance to next node } previous->next = NULL; // Unlink the last node (from its predecessor) free(current); // De-allocate deleted node return h; // Return (confirm first node was unchanged) } |
Check for edge cases.... ( Note:: the general case returns a value h ≠ NULL)
// Delete the node at the end of this list struct Node *removeLast( ) { // Detect and handle edge cases if ( h == NULL ) return NULL; // Return NULL if ( h->next == NULL ) { free(h); // De-allocated deleted node return NULL; // Return NULL } // General case The general case returns h != NULL } |
Edge case 1: empty list.... the resulting list of removeLast() is the empty list
// Delete the node at the end of this list struct Node *removeLast( ) { // Detect and handle edge cases if ( h == NULL ) // Edge case 1: the empty list return NULL; // Return the empty list if ( h->next == NULL ) { free(h); // De-allocated deleted node return NULL; // Return NULL } // General case The general case returns h != NULL } |
Edge case 2: list with a single element ---> removal results in an empty list
// Delete the node at the end of this list struct Node *removeLast( ) { // Detect and handle edge cases if ( h == NULL ) // Edge case 1: the empty list return NULL; // Return the empty list if ( h->next == NULL )// Edge case 2: the "nearly" empty list { free(h); // De-allocated deleted node return NULL; // Return the empty list } // General case The general case returns h != NULL } |
DEMO: demo/C/Linked-list/removeLast.c
|