1. Introduction
In this blog post, we explore a fundamental problem in linked list manipulation using C programming: detecting a cycle in a linked list. Detecting a cycle is a crucial issue in many applications, such as memory management and network routing. It’s a classic problem that tests one’s understanding of pointers and linked list traversal.
Problem
Given the head of a linked list, the task is to determine if the linked list contains a cycle. A cycle exists in a linked list if a node’s next pointer points back to an earlier node in the list. This problem challenges us to detect such cycles efficiently without modifying the list structure.
2. Solution Steps
1. Use two pointers: a slow pointer and a fast pointer.
2. Move the slow pointer by one step and the fast pointer by two steps in each iteration.
3. If there is a cycle, the fast pointer will eventually meet the slow pointer.
4. If the fast pointer reaches the end of the list (null), then there is no cycle.
3. Code Program
#include <stdio.h>
#include <stdlib.h>
// Definition for singly-linked list.
struct ListNode {
int val;
struct ListNode *next;
};
// Function to check if a linked list has a cycle
int hasCycle(struct ListNode *head) {
struct ListNode *slow = head, *fast = head;
while (fast && fast->next) {
slow = slow->next; // Move slow pointer by one step
fast = fast->next->next; // Move fast pointer by two steps
if (slow == fast) {
return 1; // Cycle detected
}
}
return 0; // No cycle
}
// Utility function to create a new node
struct ListNode* newNode(int val) {
struct ListNode *node = (struct ListNode*)malloc(sizeof(struct ListNode));
node->val = val;
node->next = NULL;
return node;
}
// Main function to demonstrate hasCycle function
int main() {
// Create a sample list with a cycle: 1->2->3->4->2 (cycle)
struct ListNode* head = newNode(1);
head->next = newNode(2);
head->next->next = newNode(3);
head->next->next->next = newNode(4);
head->next->next->next->next = head->next; // Creating a cycle
int result = hasCycle(head); // Call the function
printf("Output: %d\n", result); // Print the result (1 for true, 0 for false)
// Normally, we should free the list, but it's not possible due to the cycle
// Freeing the list would require breaking the cycle, which is not part of the problem
return 0;
}
Output:
1
Explanation:
The program checks for a cycle in a linked list using the two-pointer (or 'tortoise and hare') approach. Two pointers, slow and fast, traverse the list at different speeds. If there is a cycle, they will eventually meet inside the cycle. If the fast pointer reaches the end (null), it means there is no cycle.
In this example, the list 1->2->3->4->2 forms a cycle starting from the node with value 2. The program correctly identifies the presence of a cycle, hence the output is 1 (true).
This method is efficient as it traverses the list in linear time and does not require extra space.
Comments
Post a Comment