Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
* [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)
* [RotateSinglyLinkedListsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedListsTest.java)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,49 @@
package com.thealgorithms.datastructures.lists;

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

public static void main(String[] args) {
SinglyLinkedList listA = new SinglyLinkedList();
SinglyLinkedList listB = new SinglyLinkedList();

for (int i = 2; i <= 10; i += 2) {
listA.insert(i);
listB.insert(i - 1);
}
assert listA.toString().equals("2->4->6->8->10");
assert listB.toString().equals("1->3->5->7->9");
assert merge(listA, listB).toString().equals("1->2->3->4->5->6->7->8->9->10");
}

/**
* Merge two sorted SingleLinkedList
* Merges two sorted singly linked lists into a single sorted singly linked list.
*
* <p>This method does not modify the input lists; instead, it creates a new merged linked list
* containing all elements from both lists in sorted order.</p>
*
* @param listA the first sorted list
* @param listB the second sored list
* @return merged sorted list
* @param listA The first sorted singly linked list.
* @param listB The second sorted singly linked list.
* @return A new singly linked list containing all elements from both lists in sorted order.
* @throws NullPointerException if either input list is null.
*/
public static SinglyLinkedList merge(SinglyLinkedList listA, SinglyLinkedList listB) {
if (listA == null || listB == null) {
throw new NullPointerException("Input lists must not be null.");
}

Node headA = listA.getHead();
Node headB = listB.getHead();

int size = listA.size() + listB.size();

Node head = new Node();
Expand All @@ -40,12 +58,10 @@ public static SinglyLinkedList merge(SinglyLinkedList listA, SinglyLinkedList li
}
tail = tail.next;
}
if (headA == null) {
tail.next = headB;
}
if (headB == null) {
tail.next = headA;
}

// Attach remaining nodes
tail.next = (headA == null) ? headB : headA;

return new SinglyLinkedList(head.next, size);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.thealgorithms.datastructures.lists;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import org.junit.jupiter.api.Test;

class MergeSortedSinglyLinkedListTest {

@Test
void testMergeTwoSortedLists() {
SinglyLinkedList listA = new SinglyLinkedList();
SinglyLinkedList listB = new SinglyLinkedList();

for (int i = 2; i <= 10; i += 2) {
listA.insert(i);
listB.insert(i - 1);
}

SinglyLinkedList mergedList = MergeSortedSinglyLinkedList.merge(listA, listB);
assertEquals("1->2->3->4->5->6->7->8->9->10", mergedList.toString(), "Merged list should contain all elements in sorted order.");
}

@Test
void testMergeWithEmptyListA() {
SinglyLinkedList listA = new SinglyLinkedList(); // Empty listA
SinglyLinkedList listB = new SinglyLinkedList();
listB.insert(1);
listB.insert(3);
listB.insert(5);

SinglyLinkedList mergedList = MergeSortedSinglyLinkedList.merge(listA, listB);
assertEquals("1->3->5", mergedList.toString(), "Merged list should match listB when listA is empty.");
}

@Test
void testMergeWithEmptyListB() {
SinglyLinkedList listA = new SinglyLinkedList();
SinglyLinkedList listB = new SinglyLinkedList(); // Empty listB
listA.insert(2);
listA.insert(4);
listA.insert(6);

SinglyLinkedList mergedList = MergeSortedSinglyLinkedList.merge(listA, listB);
assertEquals("2->4->6", mergedList.toString(), "Merged list should match listA when listB is empty.");
}

@Test
void testMergeWithBothEmptyLists() {
SinglyLinkedList listA = new SinglyLinkedList(); // Empty listA
SinglyLinkedList listB = new SinglyLinkedList(); // Empty listB

SinglyLinkedList mergedList = MergeSortedSinglyLinkedList.merge(listA, listB);
assertEquals("", mergedList.toString(), "Merged list should be empty when both input lists are empty.");
}

@Test
void testMergeWithDuplicateValues() {
SinglyLinkedList listA = new SinglyLinkedList();
SinglyLinkedList listB = new SinglyLinkedList();

listA.insert(1);
listA.insert(3);
listA.insert(5);
listB.insert(1);
listB.insert(4);
listB.insert(5);

SinglyLinkedList mergedList = MergeSortedSinglyLinkedList.merge(listA, listB);
assertEquals("1->1->3->4->5->5", mergedList.toString(), "Merged list should include duplicate values in sorted order.");
}

@Test
void testMergeThrowsExceptionOnNullInput() {
SinglyLinkedList listA = null;
SinglyLinkedList listB = new SinglyLinkedList();
listB.insert(1);
listB.insert(2);

SinglyLinkedList finalListA = listA;
SinglyLinkedList finalListB = listB;
assertThrows(NullPointerException.class, () -> MergeSortedSinglyLinkedList.merge(finalListA, finalListB), "Should throw NullPointerException if listA is null.");

listA = new SinglyLinkedList();
listB = null;
SinglyLinkedList finalListA1 = listA;
SinglyLinkedList finalListB1 = listB;
assertThrows(NullPointerException.class, () -> MergeSortedSinglyLinkedList.merge(finalListA1, finalListB1), "Should throw NullPointerException if listB is null.");
}
}