Skip to content

Commit fd0bcb7

Browse files
authored
Add Middle of Linked List (Slow/Fast Pointers) (#7212)
* feat: implement Smooth Sort algorithm with detailed JavaDoc and test class * style: format LEONARDO array for improved readability with clang-format * feat: add MiddleOfLinkedList class and corresponding test cases * docs: update documentation for MiddleOfLinkedList class * test: refactor MiddleOfLinkedListTest to improve readability and assertions * test: refactor MiddleOfLinkedListTest for improved null safety and readability --------- Co-authored-by: Ahmed Allam <60698204+AllamF5J@users.noreply.github.com>
1 parent babc762 commit fd0bcb7

File tree

2 files changed

+120
-0
lines changed

2 files changed

+120
-0
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.thealgorithms.datastructures.lists;
2+
3+
/**
4+
* Returns the middle node of a singly linked list using the two-pointer technique.
5+
*
6+
* <p>The {@code slow} pointer advances by one node per iteration while {@code fast} advances by two.
7+
* When {@code fast == null} or {@code fast.next == null}, {@code slow} points to the middle node.
8+
* For even-length lists, this returns the <em>second</em> middle node.</p>
9+
*
10+
* <p>This method does not modify the input list.</p>
11+
*
12+
* <p>Reference: https://en.wikipedia.org/wiki/Cycle_detection#Floyd's_tortoise_and_hare</p>
13+
*
14+
* <p>Complexity:</p>
15+
* <ul>
16+
* <li>Time: {@code O(n)}</li>
17+
* <li>Space: {@code O(1)}</li>
18+
* </ul>
19+
*/
20+
public final class MiddleOfLinkedList {
21+
22+
private MiddleOfLinkedList() {
23+
}
24+
25+
/**
26+
* Returns the middle node of the list.
27+
*
28+
* @param head the head of the singly linked list; may be {@code null}
29+
* @return the middle node (second middle for even-sized lists), or {@code null} if {@code head} is {@code null}
30+
*/
31+
public static SinglyLinkedListNode middleNode(final SinglyLinkedListNode head) {
32+
if (head == null) {
33+
return null;
34+
}
35+
36+
SinglyLinkedListNode slow = head;
37+
SinglyLinkedListNode fast = head;
38+
39+
while (fast != null && fast.next != null) {
40+
slow = slow.next;
41+
fast = fast.next.next;
42+
}
43+
44+
return slow;
45+
}
46+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package com.thealgorithms.datastructures.lists;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertNull;
5+
6+
import java.util.Objects;
7+
import org.junit.jupiter.api.Test;
8+
9+
public class MiddleOfLinkedListTest {
10+
11+
private static SinglyLinkedListNode listOf(int firstValue, int... remainingValues) {
12+
SinglyLinkedListNode head = new SinglyLinkedListNode(firstValue);
13+
SinglyLinkedListNode current = head;
14+
15+
for (int i = 0; i < remainingValues.length; i++) {
16+
current.next = new SinglyLinkedListNode(remainingValues[i]);
17+
current = current.next;
18+
}
19+
return head;
20+
}
21+
22+
@Test
23+
void middleNodeOddLength() {
24+
SinglyLinkedListNode head = listOf(1, 2, 3, 4, 5);
25+
SinglyLinkedListNode middle = Objects.requireNonNull(MiddleOfLinkedList.middleNode(head));
26+
assertEquals(3, middle.value);
27+
}
28+
29+
@Test
30+
void middleNodeEvenLengthReturnsSecondMiddle() {
31+
SinglyLinkedListNode head = listOf(1, 2, 3, 4, 5, 6);
32+
SinglyLinkedListNode middle = Objects.requireNonNull(MiddleOfLinkedList.middleNode(head));
33+
assertEquals(4, middle.value);
34+
}
35+
36+
@Test
37+
void middleNodeSingleElement() {
38+
SinglyLinkedListNode head = listOf(42);
39+
SinglyLinkedListNode middle = Objects.requireNonNull(MiddleOfLinkedList.middleNode(head));
40+
assertEquals(42, middle.value);
41+
}
42+
43+
@Test
44+
void middleNodeTwoElementsReturnsSecond() {
45+
SinglyLinkedListNode head = listOf(10, 20);
46+
SinglyLinkedListNode middle = Objects.requireNonNull(MiddleOfLinkedList.middleNode(head));
47+
assertEquals(20, middle.value);
48+
}
49+
50+
@Test
51+
void middleNodeNullHead() {
52+
assertNull(MiddleOfLinkedList.middleNode(null));
53+
}
54+
55+
@Test
56+
void middleNodeDoesNotModifyListStructure() {
57+
SinglyLinkedListNode first = new SinglyLinkedListNode(1);
58+
SinglyLinkedListNode second = new SinglyLinkedListNode(2);
59+
SinglyLinkedListNode third = new SinglyLinkedListNode(3);
60+
SinglyLinkedListNode fourth = new SinglyLinkedListNode(4);
61+
62+
first.next = second;
63+
second.next = third;
64+
third.next = fourth;
65+
66+
SinglyLinkedListNode middle = Objects.requireNonNull(MiddleOfLinkedList.middleNode(first));
67+
assertEquals(3, middle.value);
68+
69+
assertEquals(second, first.next);
70+
assertEquals(third, second.next);
71+
assertEquals(fourth, third.next);
72+
assertNull(fourth.next);
73+
}
74+
}

0 commit comments

Comments
 (0)