diff --git a/DIRECTORY.md b/DIRECTORY.md index 4ceaefd6ea02..95805ff411eb 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -830,6 +830,7 @@ * lists * [CircleLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/CircleLinkedListTest.java) * [CreateAndDetectLoopTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoopTest.java) + * [MergeSortedArrayListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/MergeSortedArrayListTest.java) * [MergeSortedSinglyLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/MergeSortedSinglyLinkedListTest.java) * [QuickSortLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/QuickSortLinkedListTest.java) * [ReverseKGroupTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/ReverseKGroupTest.java) diff --git a/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedArrayList.java b/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedArrayList.java index e315c4236338..09eb854c8dc2 100644 --- a/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedArrayList.java +++ b/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedArrayList.java @@ -1,49 +1,55 @@ package com.thealgorithms.datastructures.lists; -import java.util.ArrayList; import java.util.Collection; import java.util.List; /** + * Utility class for merging two sorted ArrayLists of integers into a single sorted collection. + * + *

This class provides a static `merge` method to combine two pre-sorted lists of integers into a + * single sorted list. It does so without modifying the input lists by adding elements from both lists in sorted order + * into the result list.

+ * + *

Example usage:

+ *
+ * List listA = Arrays.asList(1, 3, 5, 7, 9);
+ * List listB = Arrays.asList(2, 4, 6, 8, 10);
+ * List result = new ArrayList<>();
+ * MergeSortedArrayList.merge(listA, listB, result);
+ * 
+ * + *

The resulting `result` list will be [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].

+ * + *

Note: This class cannot be instantiated as it is designed to be used only with its static `merge` method.

+ * + *

This implementation assumes the input lists are already sorted in ascending order.

+ * * @author https://github.com/shellhub + * @see List */ public final class MergeSortedArrayList { - private MergeSortedArrayList() { - } - - public static void main(String[] args) { - List listA = new ArrayList<>(); - List listB = new ArrayList<>(); - List listC = new ArrayList<>(); - - /* init ListA and List B */ - for (int i = 1; i <= 10; i += 2) { - listA.add(i); - /* listA: [1, 3, 5, 7, 9] */ - listB.add(i + 1); - /* listB: [2, 4, 6, 8, 10] */ - } - - /* merge listA and listB to listC */ - merge(listA, listB, listC); - System.out.println("listA: " + listA); - System.out.println("listB: " + listB); - System.out.println("listC: " + listC); + private MergeSortedArrayList() { } /** - * merge two sorted ArrayList + * Merges two sorted lists of integers into a single sorted collection. + * + *

This method does not alter the original lists (`listA` and `listB`). Instead, it inserts elements from both + * lists into `listC` in a way that maintains ascending order.

* - * @param listA the first list to merge - * @param listB the second list to merge - * @param listC the result list after merging + * @param listA The first sorted list of integers. + * @param listB The second sorted list of integers. + * @param listC The collection to hold the merged result, maintaining sorted order. + * @throws NullPointerException if any of the input lists or result collection is null. */ public static void merge(List listA, List listB, Collection listC) { + if (listA == null || listB == null || listC == null) { + throw new NullPointerException("Input lists and result collection must not be null."); + } + int pa = 0; - /* the index of listA */ int pb = 0; - /* the index of listB */ while (pa < listA.size() && pb < listB.size()) { if (listA.get(pa) <= listB.get(pb)) { @@ -53,12 +59,11 @@ public static void merge(List listA, List listB, Collection listA = Arrays.asList(1, 3, 5, 7, 9); + List listB = Arrays.asList(2, 4, 6, 8, 10); + List result = new ArrayList<>(); + + MergeSortedArrayList.merge(listA, listB, result); + + List expected = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + assertEquals(expected, result, "Merged list should be sorted and contain all elements from both input lists."); + } + + @Test + void testMergeWithEmptyList() { + List listA = Arrays.asList(1, 2, 3); + List listB = new ArrayList<>(); // Empty list + List result = new ArrayList<>(); + + MergeSortedArrayList.merge(listA, listB, result); + + List expected = Arrays.asList(1, 2, 3); + assertEquals(expected, result, "Merged list should match listA when listB is empty."); + } + + @Test + void testMergeWithBothEmptyLists() { + List listA = new ArrayList<>(); // Empty list + List listB = new ArrayList<>(); // Empty list + List result = new ArrayList<>(); + + MergeSortedArrayList.merge(listA, listB, result); + + assertTrue(result.isEmpty(), "Merged list should be empty when both input lists are empty."); + } + + @Test + void testMergeWithDuplicateElements() { + List listA = Arrays.asList(1, 2, 2, 3); + List listB = Arrays.asList(2, 3, 4); + List result = new ArrayList<>(); + + MergeSortedArrayList.merge(listA, listB, result); + + List expected = Arrays.asList(1, 2, 2, 2, 3, 3, 4); + assertEquals(expected, result, "Merged list should correctly handle and include duplicate elements."); + } + + @Test + void testMergeWithNegativeAndPositiveNumbers() { + List listA = Arrays.asList(-3, -1, 2); + List listB = Arrays.asList(-2, 0, 3); + List result = new ArrayList<>(); + + MergeSortedArrayList.merge(listA, listB, result); + + List expected = Arrays.asList(-3, -2, -1, 0, 2, 3); + assertEquals(expected, result, "Merged list should correctly handle negative and positive numbers."); + } + + @Test + void testMergeThrowsExceptionOnNullInput() { + List listA = null; + List listB = Arrays.asList(1, 2, 3); + List result = new ArrayList<>(); + + List finalListB = listB; + List finalListA = listA; + List finalResult = result; + assertThrows(NullPointerException.class, () -> MergeSortedArrayList.merge(finalListA, finalListB, finalResult), "Should throw NullPointerException if any input list is null."); + + listA = Arrays.asList(1, 2, 3); + listB = null; + List finalListA1 = listA; + List finalListB1 = listB; + List finalResult1 = result; + assertThrows(NullPointerException.class, () -> MergeSortedArrayList.merge(finalListA1, finalListB1, finalResult1), "Should throw NullPointerException if any input list is null."); + + listA = Arrays.asList(1, 2, 3); + listB = Arrays.asList(4, 5, 6); + result = null; + List finalListA2 = listA; + List finalListB2 = listB; + List finalResult2 = result; + assertThrows(NullPointerException.class, () -> MergeSortedArrayList.merge(finalListA2, finalListB2, finalResult2), "Should throw NullPointerException if the result collection is null."); + } +}