Cycle Detection in Linked Lists with Floyd's Algorithm

The problem involves verifying the presence of a closed loop within a sequence of connected nodes. Specifically, one must determine if traversing the next pointers eventually returns to a previously encountered node. While test environments may define connection indices for simulation purposse, the algorithm operates logically without reliance on these metadata values.

Efficient Strategy

The optimal solution utilizes a two-pointer technique known as Floyd's Cycle-Finding Algorithm. This approach ensures O(n) time complexity and O(1) space complexity by avoiding auxiliary storage structures like hash sets.

Core Logic

  • Initialization: Create two iterators starting at the head of the list.
  • Velocity Difference: One iterator advances one step per iterasion (pointerA), while the other advances two steps (pointerB).
  • Termination Conditions:
    • If the list is acyclic, the faster iterator will reach a null pointer first.
    • If a cycle exists, the faster iterator will eventually "lap" or meet the slower iterator within the loop.

Implementation Considerations

  1. Enput Validation: An empty list or a single-node list cannot contain a cycle. Immediate return of false is required for these edge cases.
  2. Safety Checks: Before moving the faster pointer two steps ahead, verify that both the current node and its immediate successor are valid to prevent null dereference errors.
  3. Meeting Point: Equality between the two pointers confirms the existence of a cycle.

C++ Solution

#include <iostream>

using namespace std;

// Node structure definition
struct Node {
    int data;
    Node* link;

    Node(int val) : data(val), link(nullptr) {}
};

class ListAnalyzer {
public:
    bool verifyCircularity(Node* entryPoint) {
        // Edge case: Not enough nodes to form a circle
        if (entryPoint == nullptr || entryPoint->link == nullptr) {
            return false;
        }

        Node* pointerA = entryPoint;
        Node* pointerB = entryPoint;

        // Traverse until pointerB hits the end safely
        while (pointerB != nullptr && pointerB->link != nullptr) {
            pointerA = pointerA->link;              // Advance 1 step
            pointerB = pointerB->link->link;        // Advance 2 steps

            // Collision indicates a loop
            if (pointerA == pointerB) {
                return true;
            }
        }

        // Reached tail without collision
        return false;
    }
};

int main() {
    // Case 1: Constructed with a loop
    Node* n1 = new Node(5);
    Node* n2 = new Node(10);
    Node* n3 = new Node(15);

    n1->link = n2;
    n2->link = n3;
    n3->link = n2; // n3 points back to n2, forming a cycle

    ListAnalyzer analyzer;
    cout << "Has Cycle: " << (analyzer.verifyCircularity(n1) ? "True" : "False") << endl;

    // Case 2: Linear structure (no loop)
    Node* x1 = new Node(1);
    Node* x2 = new Node(2);

    x1->link = x2;
    // x2 links to nullptr by default

    cout << "Has Cycle: " << (analyzer.verifyCircularity(x1) ? "True" : "False") << endl;

    return 0;
}

Tags: Data Structures Linked List C++ algorithms Floyd's Cycle Detection

Posted on Tue, 04 Aug 2026 16:56:34 +0000 by DigitalNinja