What is loop in linked list?
Loop in linked list means you can traverse the list endlessly. If you traverse a linked list with loop, you will hit all or some of the nodes again and again. We’ll see how this is possible.
Consider the normal (without loop) linked list above. Head points to the first node (24) and the last node (10) points to NULL. If you traverse this list starting from the head, traversal will end at node 10 because node 10 does not point to any other node. But this will not be the case of linked list with loop.
Consider the linked list with a loop above. This linked list is similar to the first one but the last node (10) here is pointing to another node (9), instead of pointing to NULL. If you traverse this list, traversal will never end. The nodes 9, 18, 6, 10 will come again and again.
In the following sections we’ll see how to write C program to detect such loop and remove from the list.
Create the linked list
First we’ll create a normal linked list by inserting nodes at the front of the list.
struct node{ int val; struct node *next; }; void print_list(struct node *head) { printf("H->"); while(head) { printf("%d->", head->val); head = head->next; } printf("|||\n"); } void insert_front(struct node **head, int value) { struct node * new_node = NULL; new_node = (struct node *)malloc(sizeof(struct node)); if (new_node == NULL) { printf("Failed to insert element. Out of memory"); } new_node->val = value; new_node->next = *head; *head = new_node; }
Read also:
We have a print_list() function here. The output of these functions will be:
Enter number of elements: 5 Enter 0th element: 10 Enter 1th element: 6 Enter 2th element: 18 Enter 3th element: 9 Enter 4th element: 24 Original List: H->24->9->18->6->10->|||
Create the loop
Function to create a loop in the above linked list.
void create_loop(struct node *head) { struct node *tmp = head; while(tmp->next) tmp = tmp->next; tmp->next = head->next; }
This function first finds the last node (which points to NULL) of the list and then points the last node to the second node of the list.
How to prove that this function will create loop? Well, after calling this function, we’ll print the list. But wait. If you use the above print_list() function to print the list, the function will fall in an infinite loop. So we’ll slightly modify the print function to print at most 25 nodes.
void print_loop(struct node *head) { int n = 25; printf("H->"); while(n--) { printf("%d->", head->val); head = head->next; } printf("|||\n"); }
Output of the function will be:
H->24->9->18->6->10->9->18->6->10->9->18->6->10->9->18->6->10->9->18->6->10->9->18->6->10->|||
Here you can see, the nodes 9, 18, 6, 10 are coming again and again.
Function to detect loop in linked list
void detect_loop(struct node *head) { struct node *slow = head; struct node *fast = head; while(slow && fast->next && fast->next->next) { if ((slow == fast->next) || (slow == fast->next->next )) { printf("Linked list has a loop.\n"); return; } slow = slow->next; fast = fast->next->next; } printf("Linked list does not have any loop.\n"); }
This function detects loop with the help of two pointers slow and fast. Both slow and fast will start from head and in every iteration slow will move one position and fast will move two positions. In any iteration, if slow or fast->next or fast->next->next becomes NULL, that means there is no loop in the linked list. And if fast->next or fast->next->next becomes equal to slow, that means the linked list has a loop.
Function to remove loop from linked list
Removing loop from linked list is simple; assign the last node to NULL. If no node points to NULL, the which one is the last? Well, in a linked list with loop, there will be one node which will be pointed by two nodes; one of them is the last node. Which one? The one whose distance from head is more.
Here is the function to remove loop:
void remove_loop(struct node *head) { struct node *slow = head; struct node *fast = head; while(slow && fast->next && fast->next->next) { if (slow == fast->next) { fast->next = NULL; break; } if (slow == fast->next->next) { fast->next->next = NULL; break; } slow = slow->next; fast = fast->next->next; } }
The complete program
The complete program is copied here to compile and run.
#include <stdio.h> #include <stdlib.h> struct node{ int val; struct node *next; }; void print_list(struct node *head) { printf("H->"); while(head) { printf("%d->", head->val); head = head->next; } printf("|||\n"); } void insert_front(struct node **head, int value) { struct node * new_node = NULL; new_node = (struct node *)malloc(sizeof(struct node)); if (new_node == NULL) { printf("Failed to insert element. Out of memory"); } new_node->val = value; new_node->next = *head; *head = new_node; } void create_loop(struct node *head) { struct node *tmp = head; while(tmp->next) tmp = tmp->next; tmp->next = head->next; } void print_loop(struct node *head) { int n = 25; printf("H->"); while(n--) { printf("%d->", head->val); head = head->next; } printf("|||\n"); } void detect_loop(struct node *head) { struct node *slow = head; struct node *fast = head; while(slow && fast->next && fast->next->next) { if ((slow == fast->next) || (slow == fast->next->next )) { printf("Linked list has a loop.\n"); return; } slow = slow->next; fast = fast->next->next; } printf("Linked list does not have any loop.\n"); } void remove_loop(struct node *head) { struct node *slow = head; struct node *fast = head; while(slow && fast->next && fast->next->next) { if (slow == fast->next) { fast->next = NULL; break; } if (slow == fast->next->next) { fast->next->next = NULL; break; } slow = slow->next; fast = fast->next->next; } } void main() { int count = 0, i, val; struct node * head = NULL; printf("Enter number of elements: "); scanf("%d", &count); for (i = 0; i < count; i++) { printf("Enter %dth element: ", i); scanf("%d", &val); insert_front(&head, val); } printf("Original List: "); print_list(head); detect_loop(head); create_loop(head); print_loop(head); detect_loop(head); printf("Removing loop...\n"); remove_loop(head); detect_loop(head); }
Output:
Enter number of elements: 5 Enter 0th element: 10 Enter 1th element: 6 Enter 2th element: 18 Enter 3th element: 9 Enter 4th element: 24 Original List: H->24->9->18->6->10->||| Linked list does not have any loop. H->24->9->18->6->10->9->18->6->10->9->18->6->10->9->18->6->10->9->18->6->10->9->18->6->10->||| Linked list has a loop. Removing loop... Linked list does not have any loop.
The post Loop in Linked List, C Program to Detect and Remove appeared first on QnA Plus.