Using pointers, loop through the whole list and keep track of the node prior to the node containing the last occurrence key using a special pointer. After this just store the next of next of the special pointer, into to next of special pointer to remove the required node from the linked list.
#include <stdio.h> #include <stdlib.h> // A linked list Node struct Node
{ int data;
struct Node* next;
}; // Function to delete the last // occurrence void deleteLast( struct Node** head,
int x)
{ struct Node** tmp1 = NULL;
while (*head)
{
if ((*head)->data == x)
{
tmp1 = head;
}
head = &(*head)->next;
}
if (tmp1)
{
struct Node* tmp = *tmp1;
*tmp1 = tmp->next;
free (tmp);
}
} /* Utility function to create a new node with given key */
struct Node* newNode( int x)
{ struct Node* node =
malloc ( sizeof ( struct Node*));
node->data = x;
node->next = NULL;
return node;
} // This function prints contents of // linked list starting from the given // Node void display( struct Node* head)
{ struct Node* temp = head;
if (head == NULL)
{
printf ( "NULL" );
return ;
}
while (temp != NULL)
{
printf ( "%d --> " ,
temp->data);
temp = temp->next;
}
printf ( "NULL" );
} // Driver code int main()
{ struct Node* head = newNode(1);
head->next = newNode(2);
head->next->next =
newNode(3);
head->next->next->next =
newNode(4);
head->next->next->next->next =
newNode(5);
head->next->next->next->next->next =
newNode(4);
head->next->next->next->next->next->next =
newNode(4);
printf ( "Created Linked list: " );
display(head);
// Pass the address of the head pointer
deleteLast(&head, 4);
printf ( "List after deletion of 4: " );
display(head);
return 0;
} |
Output:
Created Linked list: 1 --> 2 --> 3 --> 4 --> 5 --> 4 --> 4 --> NULL List after deletion of 4: 1 --> 2 --> 3 --> 4 --> 5 --> 4 --> NULL
Time Complexity: O(n) where n is the number of nodes in the given linked list.
Auxiliary Space: O(1), no extra space is required, so it is a constant.
The above solution doesn’t work when the node to be deleted is the last node.
Following solution handles all cases.
// A C program to demonstrate deletion // of last Node in singly linked list #include <stdio.h> #include <stdlib.h> // A linked list Node struct Node
{ int data;
struct Node* next;
}; // Function to delete the last // occurrence void deleteLast( struct Node* head,
int x)
{ struct Node *temp = head,
*ptr = NULL;
while (temp)
{
// If found key, update
if (temp->data == x)
ptr = temp;
temp = temp->next;
}
// If the last occurrence is the
// last node
if (ptr != NULL &&
ptr->next == NULL)
{
temp = head;
while (temp->next != ptr)
temp = temp->next;
temp->next = NULL;
}
// If it is not the last node
if (ptr != NULL &&
ptr->next != NULL)
{
ptr->data = ptr->next->data;
temp = ptr->next;
ptr->next = ptr->next->next;
free (temp);
}
} /* Utility function to create a new node with given key */
struct Node* newNode( int x)
{ struct Node* node =
malloc ( sizeof ( struct Node*));
node->data = x;
node->next = NULL;
return node;
} // This function prints contents of // linked list starting from the given // Node void display( struct Node* head)
{ struct Node* temp = head;
if (head == NULL)
{
printf ( "NULL" );
return ;
}
while (temp != NULL)
{
printf ( "%d --> " , temp->data);
temp = temp->next;
}
printf ( "NULL" );
} // Driver code int main()
{ struct Node* head = newNode(1);
head->next = newNode(2);
head->next->next = newNode(3);
head->next->next->next =
newNode(4);
head->next->next->next->next =
newNode(5);
head->next->next->next->next->next =
newNode(4);
head->next->next->next->next->next->next =
newNode(4);
printf ( "Created Linked list: " );
display(head);
deleteLast(head, 4);
printf ( "List after deletion of 4: " );
display(head);
return 0;
} |
Output:
Created Linked List: 1 2 3 4 5 4 4 Linked List after Deletion of 1: 1 2 3 4 5 4
Time Complexity: O(n) where n is the number of nodes in the given linked list.
Auxiliary Space: O(1), no extra space is required, so it is a constant.
Please refer complete article on Delete last occurrence of an item from linked list for more details!