Skip to content

Commit b6c1e5c

Browse files
committed
feat: add MiddleOfLinkedList class and corresponding test cases
1 parent 8bf1a0e commit b6c1e5c

2 files changed

Lines changed: 115 additions & 0 deletions

File tree

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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>Complexity:</p>
13+
* <ul>
14+
* <li>Time: {@code O(n)}</li>
15+
* <li>Space: {@code O(1)}</li>
16+
* </ul>
17+
*/
18+
public final class MiddleOfLinkedList {
19+
20+
private MiddleOfLinkedList() {
21+
}
22+
23+
/**
24+
* Returns the middle node of the list.
25+
*
26+
* @param head the head of the singly linked list; may be {@code null}
27+
* @return the middle node (second middle for even-sized lists), or {@code null} if {@code head} is {@code null}
28+
*/
29+
public static SinglyLinkedListNode middleNode(final SinglyLinkedListNode head) {
30+
if (head == null) {
31+
return null;
32+
}
33+
34+
SinglyLinkedListNode slow = head;
35+
SinglyLinkedListNode fast = head;
36+
37+
while (fast != null && fast.next != null) {
38+
slow = slow.next;
39+
fast = fast.next.next;
40+
}
41+
42+
return slow;
43+
}
44+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
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 org.junit.jupiter.api.Test;
7+
8+
public class MiddleOfLinkedListTest {
9+
10+
private static SinglyLinkedListNode listOf(int... values) {
11+
if (values == null || values.length == 0) {
12+
return null;
13+
}
14+
15+
SinglyLinkedListNode head = new SinglyLinkedListNode(values[0]);
16+
SinglyLinkedListNode current = head;
17+
for (int i = 1; i < values.length; i++) {
18+
current.next = new SinglyLinkedListNode(values[i]);
19+
current = current.next;
20+
}
21+
return head;
22+
}
23+
24+
@Test
25+
void middleNodeOddLength() {
26+
SinglyLinkedListNode head = listOf(1, 2, 3, 4, 5);
27+
assertEquals(3, MiddleOfLinkedList.middleNode(head).value);
28+
}
29+
30+
@Test
31+
void middleNodeEvenLengthReturnsSecondMiddle() {
32+
SinglyLinkedListNode head = listOf(1, 2, 3, 4, 5, 6);
33+
assertEquals(4, MiddleOfLinkedList.middleNode(head).value);
34+
}
35+
36+
@Test
37+
void middleNodeSingleElement() {
38+
SinglyLinkedListNode head = listOf(42);
39+
assertEquals(42, MiddleOfLinkedList.middleNode(head).value);
40+
}
41+
42+
@Test
43+
void middleNodeTwoElementsReturnsSecond() {
44+
SinglyLinkedListNode head = listOf(10, 20);
45+
assertEquals(20, MiddleOfLinkedList.middleNode(head).value);
46+
}
47+
48+
@Test
49+
void middleNodeNullHead() {
50+
assertNull(MiddleOfLinkedList.middleNode(null));
51+
}
52+
53+
@Test
54+
void middleNodeDoesNotModifyListStructure() {
55+
SinglyLinkedListNode first = new SinglyLinkedListNode(1);
56+
SinglyLinkedListNode second = new SinglyLinkedListNode(2);
57+
SinglyLinkedListNode third = new SinglyLinkedListNode(3);
58+
SinglyLinkedListNode fourth = new SinglyLinkedListNode(4);
59+
60+
first.next = second;
61+
second.next = third;
62+
third.next = fourth;
63+
64+
assertEquals(3, MiddleOfLinkedList.middleNode(first).value);
65+
66+
assertEquals(second, first.next);
67+
assertEquals(third, second.next);
68+
assertEquals(fourth, third.next);
69+
assertNull(fourth.next);
70+
}
71+
}

0 commit comments

Comments
 (0)