From f51ffa7d3ca195803d4a62cc584c6f8f2d74da53 Mon Sep 17 00:00:00 2001 From: sowmya-rebbavarapu Date: Sat, 24 May 2025 12:16:59 +0530 Subject: [PATCH] Add linked list cycle detection tests and cycle creation utility --- .../linked-list/cycle/__tests__/cycle.test.js | 50 +++++++++++++++++++ .../linked-list/cycle/createCycle.js | 24 +++++++++ .../linked-list/cycle/detectCycle.js | 15 ++++++ 3 files changed, 89 insertions(+) create mode 100644 src/algorithms/linked-list/cycle/__tests__/cycle.test.js create mode 100644 src/algorithms/linked-list/cycle/createCycle.js create mode 100644 src/algorithms/linked-list/cycle/detectCycle.js diff --git a/src/algorithms/linked-list/cycle/__tests__/cycle.test.js b/src/algorithms/linked-list/cycle/__tests__/cycle.test.js new file mode 100644 index 0000000000..da76bc14c7 --- /dev/null +++ b/src/algorithms/linked-list/cycle/__tests__/cycle.test.js @@ -0,0 +1,50 @@ +import LinkedList from '../../../../data-structures/linked-list/LinkedList'; +import createCycle from '../createCycle'; +import detectCycle from '../detectCycle'; + +describe('Linked List Cycle Tests', () => { + let list; + + beforeEach(() => { + list = new LinkedList(); + }); + + test('detectCycle returns false on list with no cycle', () => { + list + .append(1) + .append(9) + .append(87) + .append(5) + .append(22); + expect(detectCycle(list)).toBe(false); + }); + + test('createCycle creates a cycle and detectCycle detects it', () => { + list + .append(1) + .append(9) + .append(87) + .append(5) + .append(22); + createCycle(list, 2); // Creates cycle linking tail to node at index 2 (value 87) + expect(detectCycle(list)).toBe(true); + }); + + test('createCycle with invalid position does not create cycle', () => { + list + .append(1) + .append(9) + .append(87); + createCycle(list, 10); // Invalid index, no cycle should be created + expect(detectCycle(list)).toBe(false); + }); + + test('createCycle with position -1 does not create cycle', () => { + list + .append(1) + .append(9) + .append(87); + createCycle(list, -1); // No cycle created + expect(detectCycle(list)).toBe(false); + }); +}); diff --git a/src/algorithms/linked-list/cycle/createCycle.js b/src/algorithms/linked-list/cycle/createCycle.js new file mode 100644 index 0000000000..88d43120db --- /dev/null +++ b/src/algorithms/linked-list/cycle/createCycle.js @@ -0,0 +1,24 @@ +export default function createCycle(linkedList, position) { + if (!linkedList.head || position < 0) return; + + let cycleNode = null; + let tail = linkedList.head; + let index = 0; + + while (tail.next) { + if (index === position) { + cycleNode = tail; + } + tail = tail.next; + index += 1; + } + + // For the last node + if (index === position) { + cycleNode = tail; + } + + if (cycleNode) { + tail.next = cycleNode; + } +} diff --git a/src/algorithms/linked-list/cycle/detectCycle.js b/src/algorithms/linked-list/cycle/detectCycle.js new file mode 100644 index 0000000000..e45a34729d --- /dev/null +++ b/src/algorithms/linked-list/cycle/detectCycle.js @@ -0,0 +1,15 @@ +export default function detectCycle(linkedList) { + let slow = linkedList.head; + let fast = linkedList.head; + + while (fast && fast.next) { + slow = slow.next; + fast = fast.next.next; + + if (slow === fast) { + return true; + } + } + + return false; +}