Skip to content

Commit 42b9a96

Browse files
authored
Merge branch 'master' into cursor_ll_improve
2 parents d69b5b4 + cd87dc3 commit 42b9a96

9 files changed

+394
-111
lines changed

DIRECTORY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,8 @@
831831
* [CircleLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/CircleLinkedListTest.java)
832832
* [CreateAndDetectLoopTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoopTest.java)
833833
* [CursorLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/CursorLinkedListTest.java)
834+
* [MergeSortedArrayListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/MergeSortedArrayListTest.java)
835+
* [MergeSortedSinglyLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/MergeSortedSinglyLinkedListTest.java)
834836
* [QuickSortLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/QuickSortLinkedListTest.java)
835837
* [ReverseKGroupTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/ReverseKGroupTest.java)
836838
* [RotateSinglyLinkedListsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedListsTest.java)

src/main/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoop.java

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,24 @@
11
package com.thealgorithms.datastructures.lists;
22

3+
/**
4+
* CreateAndDetectLoop provides utility methods for creating and detecting loops
5+
* (cycles) in a singly linked list. Loops in a linked list are created by
6+
* connecting the "next" pointer of one node to a previous node in the list,
7+
* forming a cycle.
8+
*/
39
public final class CreateAndDetectLoop {
410

5-
// Node class representing a single node in the linked list
11+
/**
12+
* Private constructor to prevent instantiation of this utility class.
13+
*/
614
private CreateAndDetectLoop() {
715
throw new UnsupportedOperationException("Utility class");
816
}
17+
18+
/**
19+
* Node represents an individual element in the linked list, containing
20+
* data and a reference to the next node.
21+
*/
922
static final class Node {
1023
int data;
1124
Node next;
@@ -16,19 +29,16 @@ static final class Node {
1629
}
1730
}
1831

19-
// Method to create a loop between two specific positions in the linked list
20-
/*
21-
* Test case that shows the Cycle(loop) in a LinkedList
22-
* Let's take this linked list:
23-
* 1->2->3->4->5->6
24-
* \______/
25-
* In this linked list we can see there is a cycle.
26-
* we can create loop by calling createLoop function in main after creating LL
27-
* createLoop(head,2,5);
28-
* to detect there is loop or not we can call detectloop function in main
29-
* detectloop(head);
32+
/**
33+
* Creates a loop in a linked list by connecting the next pointer of a node
34+
* at a specified starting position (position2) to another node at a specified
35+
* destination position (position1). If either position is invalid, no loop
36+
* will be created.
37+
*
38+
* @param head the head node of the linked list
39+
* @param position1 the position in the list where the loop should end
40+
* @param position2 the position in the list where the loop should start
3041
*/
31-
3242
static void createLoop(Node head, int position1, int position2) {
3343
if (position1 == 0 || position2 == 0) {
3444
return;
@@ -39,29 +49,32 @@ static void createLoop(Node head, int position1, int position2) {
3949

4050
int count1 = 1;
4151
int count2 = 1;
42-
// Traverse to find node at position1
52+
// Traverse to the node at position1
4353
while (count1 < position1 && node1 != null) {
4454
node1 = node1.next;
4555
count1++;
4656
}
4757

48-
// Traverse to find node at position2
58+
// Traverse to the node at position2
4959
while (count2 < position2 && node2 != null) {
5060
node2 = node2.next;
5161
count2++;
5262
}
5363

54-
// Create a loop by connecting node2's next to node1
64+
// If both nodes are valid, create the loop
5565
if (node1 != null && node2 != null) {
5666
node2.next = node1;
5767
}
5868
}
59-
// Method to detect a loop in the linked list
69+
6070
/**
61-
* Detects the presence of a loop in the linked list.
71+
* Detects the presence of a loop in the linked list using Floyd's cycle-finding
72+
* algorithm, also known as the "tortoise and hare" method.
6273
*
63-
* @see <a href="https://en.wikipedia.org/wiki/Cycle_detection#Floyd's_tortoise_and_hare">Floyd's Cycle Detection Algorithm</a>
64-
* @return true if loop exists else false
74+
* @param head the head node of the linked list
75+
* @return true if a loop is detected, false otherwise
76+
* @see <a href="https://en.wikipedia.org/wiki/Cycle_detection#Floyd's_tortoise_and_hare">
77+
* Floyd's Cycle Detection Algorithm</a>
6578
*/
6679
static boolean detectLoop(Node head) {
6780
Node sptr = head;

src/main/java/com/thealgorithms/datastructures/lists/MergeSortedArrayList.java

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,55 @@
11
package com.thealgorithms.datastructures.lists;
22

3-
import java.util.ArrayList;
43
import java.util.Collection;
54
import java.util.List;
65

76
/**
7+
* Utility class for merging two sorted ArrayLists of integers into a single sorted collection.
8+
*
9+
* <p>This class provides a static `merge` method to combine two pre-sorted lists of integers into a
10+
* single sorted list. It does so without modifying the input lists by adding elements from both lists in sorted order
11+
* into the result list.</p>
12+
*
13+
* <p>Example usage:</p>
14+
* <pre>
15+
* List<Integer> listA = Arrays.asList(1, 3, 5, 7, 9);
16+
* List<Integer> listB = Arrays.asList(2, 4, 6, 8, 10);
17+
* List<Integer> result = new ArrayList<>();
18+
* MergeSortedArrayList.merge(listA, listB, result);
19+
* </pre>
20+
*
21+
* <p>The resulting `result` list will be [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].</p>
22+
*
23+
* <p>Note: This class cannot be instantiated as it is designed to be used only with its static `merge` method.</p>
24+
*
25+
* <p>This implementation assumes the input lists are already sorted in ascending order.</p>
26+
*
827
* @author https://github.com/shellhub
28+
* @see List
929
*/
1030
public final class MergeSortedArrayList {
11-
private MergeSortedArrayList() {
12-
}
13-
14-
public static void main(String[] args) {
15-
List<Integer> listA = new ArrayList<>();
16-
List<Integer> listB = new ArrayList<>();
17-
List<Integer> listC = new ArrayList<>();
18-
19-
/* init ListA and List B */
20-
for (int i = 1; i <= 10; i += 2) {
21-
listA.add(i);
22-
/* listA: [1, 3, 5, 7, 9] */
23-
listB.add(i + 1);
24-
/* listB: [2, 4, 6, 8, 10] */
25-
}
26-
27-
/* merge listA and listB to listC */
28-
merge(listA, listB, listC);
2931

30-
System.out.println("listA: " + listA);
31-
System.out.println("listB: " + listB);
32-
System.out.println("listC: " + listC);
32+
private MergeSortedArrayList() {
3333
}
3434

3535
/**
36-
* merge two sorted ArrayList
36+
* Merges two sorted lists of integers into a single sorted collection.
37+
*
38+
* <p>This method does not alter the original lists (`listA` and `listB`). Instead, it inserts elements from both
39+
* lists into `listC` in a way that maintains ascending order.</p>
3740
*
38-
* @param listA the first list to merge
39-
* @param listB the second list to merge
40-
* @param listC the result list after merging
41+
* @param listA The first sorted list of integers.
42+
* @param listB The second sorted list of integers.
43+
* @param listC The collection to hold the merged result, maintaining sorted order.
44+
* @throws NullPointerException if any of the input lists or result collection is null.
4145
*/
4246
public static void merge(List<Integer> listA, List<Integer> listB, Collection<Integer> listC) {
47+
if (listA == null || listB == null || listC == null) {
48+
throw new NullPointerException("Input lists and result collection must not be null.");
49+
}
50+
4351
int pa = 0;
44-
/* the index of listA */
4552
int pb = 0;
46-
/* the index of listB */
4753

4854
while (pa < listA.size() && pb < listB.size()) {
4955
if (listA.get(pa) <= listB.get(pb)) {
@@ -53,12 +59,11 @@ public static void merge(List<Integer> listA, List<Integer> listB, Collection<In
5359
}
5460
}
5561

56-
/* copy left element of listA to listC */
62+
// Add remaining elements from listA, if any
5763
while (pa < listA.size()) {
5864
listC.add(listA.get(pa++));
5965
}
60-
61-
/* copy left element of listB to listC */
66+
// Add remaining elements from listB, if any
6267
while (pb < listB.size()) {
6368
listC.add(listB.get(pb++));
6469
}
Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,49 @@
11
package com.thealgorithms.datastructures.lists;
22

3+
/**
4+
* Utility class for merging two sorted singly linked lists.
5+
*
6+
* <p>This class extends the {@link SinglyLinkedList} class to support the merging of two sorted linked lists.
7+
* It provides a static method, `merge`, that takes two sorted singly linked lists, merges them into a single sorted linked list,
8+
* and returns the result.</p>
9+
*
10+
* <p>Example usage:</p>
11+
* <pre>
12+
* SinglyLinkedList listA = new SinglyLinkedList();
13+
* SinglyLinkedList listB = new SinglyLinkedList();
14+
* for (int i = 2; i <= 10; i += 2) {
15+
* listA.insert(i); // listA: 2->4->6->8->10
16+
* listB.insert(i - 1); // listB: 1->3->5->7->9
17+
* }
18+
* SinglyLinkedList mergedList = MergeSortedSinglyLinkedList.merge(listA, listB);
19+
* System.out.println(mergedList); // Output: 1->2->3->4->5->6->7->8->9->10
20+
* </pre>
21+
*
22+
* <p>The `merge` method assumes that both input lists are already sorted in ascending order.
23+
* It returns a new singly linked list that contains all elements from both lists in sorted order.</p>
24+
*
25+
* @see SinglyLinkedList
26+
*/
327
public class MergeSortedSinglyLinkedList extends SinglyLinkedList {
428

5-
public static void main(String[] args) {
6-
SinglyLinkedList listA = new SinglyLinkedList();
7-
SinglyLinkedList listB = new SinglyLinkedList();
8-
9-
for (int i = 2; i <= 10; i += 2) {
10-
listA.insert(i);
11-
listB.insert(i - 1);
12-
}
13-
assert listA.toString().equals("2->4->6->8->10");
14-
assert listB.toString().equals("1->3->5->7->9");
15-
assert merge(listA, listB).toString().equals("1->2->3->4->5->6->7->8->9->10");
16-
}
17-
1829
/**
19-
* Merge two sorted SingleLinkedList
30+
* Merges two sorted singly linked lists into a single sorted singly linked list.
31+
*
32+
* <p>This method does not modify the input lists; instead, it creates a new merged linked list
33+
* containing all elements from both lists in sorted order.</p>
2034
*
21-
* @param listA the first sorted list
22-
* @param listB the second sored list
23-
* @return merged sorted list
35+
* @param listA The first sorted singly linked list.
36+
* @param listB The second sorted singly linked list.
37+
* @return A new singly linked list containing all elements from both lists in sorted order.
38+
* @throws NullPointerException if either input list is null.
2439
*/
2540
public static SinglyLinkedList merge(SinglyLinkedList listA, SinglyLinkedList listB) {
41+
if (listA == null || listB == null) {
42+
throw new NullPointerException("Input lists must not be null.");
43+
}
44+
2645
Node headA = listA.getHead();
2746
Node headB = listB.getHead();
28-
2947
int size = listA.size() + listB.size();
3048

3149
Node head = new Node();
@@ -40,12 +58,10 @@ public static SinglyLinkedList merge(SinglyLinkedList listA, SinglyLinkedList li
4058
}
4159
tail = tail.next;
4260
}
43-
if (headA == null) {
44-
tail.next = headB;
45-
}
46-
if (headB == null) {
47-
tail.next = headA;
48-
}
61+
62+
// Attach remaining nodes
63+
tail.next = (headA == null) ? headB : headA;
64+
4965
return new SinglyLinkedList(head.next, size);
5066
}
5167
}

src/main/java/com/thealgorithms/datastructures/lists/QuickSortLinkedList.java

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -104,36 +104,52 @@
104104

105105
public class QuickSortLinkedList {
106106

107-
private SinglyLinkedList list = null; // Linked list
108-
private Node head = null; // head of the list
109-
// Counstructor
107+
private final SinglyLinkedList list; // The linked list to be sorted
108+
private Node head; // Head of the list
109+
110+
/**
111+
* Constructor that initializes the QuickSortLinkedList with a given linked list.
112+
*
113+
* @param list The singly linked list to be sorted
114+
*/
110115
public QuickSortLinkedList(SinglyLinkedList list) {
111116
this.list = list;
112117
this.head = list.getHead();
113118
}
114119

115-
// Function to sort a linked list using the Quick Sort algorithm
120+
/**
121+
* Sorts the linked list using the QuickSort algorithm.
122+
* The sorted list replaces the original list within the SinglyLinkedList instance.
123+
*/
116124
public void sortList() {
117125
head = sortList(head);
118126
list.setHead(head);
119127
}
120-
// helper function to apply QuickSort to the stored list
121-
public Node sortList(Node head) {
128+
129+
/**
130+
* Recursively sorts a linked list by partitioning it around a pivot element.
131+
*
132+
* <p>Each recursive call selects a pivot, partitions the list into elements less
133+
* than the pivot and elements greater than or equal to the pivot, then combines
134+
* the sorted sublists around the pivot.</p>
135+
*
136+
* @param head The head node of the list to sort
137+
* @return The head node of the sorted linked list
138+
*/
139+
private Node sortList(Node head) {
122140
if (head == null || head.next == null) {
123141
return head;
124142
}
125143

126-
// Choose the first element as the pivot
127144
Node pivot = head;
128145
head = head.next;
129146
pivot.next = null;
130147

131-
Node lessHead = new Node(); // stores the nodes cantaining data less than pivot node
132-
Node lessTail = lessHead; // tail of lessHead
133-
Node greaterHead = new Node(); // stores the nodes cantaining data greater than pivot node
134-
Node greaterTail = greaterHead; // tail of greaterHead
148+
Node lessHead = new Node();
149+
Node lessTail = lessHead;
150+
Node greaterHead = new Node();
151+
Node greaterTail = greaterHead;
135152

136-
// Partition the list around the pivot
137153
while (head != null) {
138154
if (head.value < pivot.value) {
139155
lessTail.next = head;
@@ -145,15 +161,12 @@ public Node sortList(Node head) {
145161
head = head.next;
146162
}
147163

148-
// Seperating lessHead and greaterHead to form two seperate linkedList
149164
lessTail.next = null;
150165
greaterTail.next = null;
151166

152-
// Recursively sort the sublists
153167
Node sortedLess = sortList(lessHead.next);
154168
Node sortedGreater = sortList(greaterHead.next);
155169

156-
// Combine the sorted sublists and pivot
157170
if (sortedLess == null) {
158171
pivot.next = sortedGreater;
159172
return pivot;

0 commit comments

Comments
 (0)