Enhance docs, add tests in QuickSortLinkedList (#5998)

This commit is contained in:
Hardik Pawar
2024-10-25 19:50:59 +05:30
committed by GitHub
parent 5246f63579
commit 6f489e5704
2 changed files with 76 additions and 33 deletions

View File

@ -104,36 +104,52 @@ package com.thealgorithms.datastructures.lists;
public class QuickSortLinkedList { public class QuickSortLinkedList {
private SinglyLinkedList list = null; // Linked list private final SinglyLinkedList list; // The linked list to be sorted
private Node head = null; // head of the list private Node head; // Head of the list
// Counstructor
/**
* Constructor that initializes the QuickSortLinkedList with a given linked list.
*
* @param list The singly linked list to be sorted
*/
public QuickSortLinkedList(SinglyLinkedList list) { public QuickSortLinkedList(SinglyLinkedList list) {
this.list = list; this.list = list;
this.head = list.getHead(); this.head = list.getHead();
} }
// Function to sort a linked list using the Quick Sort algorithm /**
* Sorts the linked list using the QuickSort algorithm.
* The sorted list replaces the original list within the SinglyLinkedList instance.
*/
public void sortList() { public void sortList() {
head = sortList(head); head = sortList(head);
list.setHead(head); list.setHead(head);
} }
// helper function to apply QuickSort to the stored list
public Node sortList(Node head) { /**
* Recursively sorts a linked list by partitioning it around a pivot element.
*
* <p>Each recursive call selects a pivot, partitions the list into elements less
* than the pivot and elements greater than or equal to the pivot, then combines
* the sorted sublists around the pivot.</p>
*
* @param head The head node of the list to sort
* @return The head node of the sorted linked list
*/
private Node sortList(Node head) {
if (head == null || head.next == null) { if (head == null || head.next == null) {
return head; return head;
} }
// Choose the first element as the pivot
Node pivot = head; Node pivot = head;
head = head.next; head = head.next;
pivot.next = null; pivot.next = null;
Node lessHead = new Node(); // stores the nodes cantaining data less than pivot node Node lessHead = new Node();
Node lessTail = lessHead; // tail of lessHead Node lessTail = lessHead;
Node greaterHead = new Node(); // stores the nodes cantaining data greater than pivot node Node greaterHead = new Node();
Node greaterTail = greaterHead; // tail of greaterHead Node greaterTail = greaterHead;
// Partition the list around the pivot
while (head != null) { while (head != null) {
if (head.value < pivot.value) { if (head.value < pivot.value) {
lessTail.next = head; lessTail.next = head;
@ -145,15 +161,12 @@ public class QuickSortLinkedList {
head = head.next; head = head.next;
} }
// Seperating lessHead and greaterHead to form two seperate linkedList
lessTail.next = null; lessTail.next = null;
greaterTail.next = null; greaterTail.next = null;
// Recursively sort the sublists
Node sortedLess = sortList(lessHead.next); Node sortedLess = sortList(lessHead.next);
Node sortedGreater = sortList(greaterHead.next); Node sortedGreater = sortList(greaterHead.next);
// Combine the sorted sublists and pivot
if (sortedLess == null) { if (sortedLess == null) {
pivot.next = sortedGreater; pivot.next = sortedGreater;
return pivot; return pivot;

View File

@ -4,8 +4,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
/** /**
* Test cases for QuickSortLinkedList * Test cases for QuickSortLinkedList.
* Author: Prabhat-Kumar-42 * Author: Prabhat-Kumar-42
* GitHub: https://github.com/Prabhat-Kumar-42 * GitHub: https://github.com/Prabhat-Kumar-42
*/ */
@ -16,9 +17,8 @@ public class QuickSortLinkedListTest {
SinglyLinkedList emptyList = new SinglyLinkedList(); SinglyLinkedList emptyList = new SinglyLinkedList();
QuickSortLinkedList sorter = new QuickSortLinkedList(emptyList); QuickSortLinkedList sorter = new QuickSortLinkedList(emptyList);
// Test case: Sorting an empty list should result in an empty list
sorter.sortList(); sorter.sortList();
assertNull(emptyList.getHead()); assertNull(emptyList.getHead(), "Sorted empty list should have no elements.");
} }
@Test @Test
@ -27,10 +27,51 @@ public class QuickSortLinkedListTest {
singleNodeList.insert(5); singleNodeList.insert(5);
QuickSortLinkedList sorter = new QuickSortLinkedList(singleNodeList); QuickSortLinkedList sorter = new QuickSortLinkedList(singleNodeList);
// Test case: Sorting a list with a single node should result in the same list
sorter.sortList(); sorter.sortList();
assertEquals(5, singleNodeList.getHead().value); assertEquals(5, singleNodeList.getHead().value, "Single node list should remain unchanged after sorting.");
assertNull(singleNodeList.getHead().next); assertNull(singleNodeList.getHead().next, "Single node should not have a next node.");
}
@Test
public void testSortAlreadySorted() {
SinglyLinkedList sortedList = new SinglyLinkedList();
sortedList.insert(1);
sortedList.insert(2);
sortedList.insert(3);
sortedList.insert(4);
sortedList.insert(5);
QuickSortLinkedList sorter = new QuickSortLinkedList(sortedList);
sorter.sortList();
assertEquals("1->2->3->4->5", sortedList.toString(), "Already sorted list should remain unchanged.");
}
@Test
public void testSortReverseOrderedList() {
SinglyLinkedList reverseList = new SinglyLinkedList();
reverseList.insert(5);
reverseList.insert(4);
reverseList.insert(3);
reverseList.insert(2);
reverseList.insert(1);
QuickSortLinkedList sorter = new QuickSortLinkedList(reverseList);
sorter.sortList();
assertEquals("1->2->3->4->5", reverseList.toString(), "Reverse ordered list should be sorted in ascending order.");
}
@Test
public void testSortWithDuplicates() {
SinglyLinkedList listWithDuplicates = new SinglyLinkedList();
listWithDuplicates.insert(3);
listWithDuplicates.insert(1);
listWithDuplicates.insert(3);
listWithDuplicates.insert(2);
listWithDuplicates.insert(2);
QuickSortLinkedList sorter = new QuickSortLinkedList(listWithDuplicates);
sorter.sortList();
assertEquals("1->2->2->3->3", listWithDuplicates.toString(), "List with duplicates should be sorted correctly.");
} }
@Test @Test
@ -48,18 +89,7 @@ public class QuickSortLinkedListTest {
list.insert(6); list.insert(6);
QuickSortLinkedList sorter = new QuickSortLinkedList(list); QuickSortLinkedList sorter = new QuickSortLinkedList(list);
// Test case: Sorting a list with multiple elements
sorter.sortList(); sorter.sortList();
assertEquals(1, list.getHead().value); assertEquals("1->2->3->4->5->6->7->8->9->10", list.toString(), "List should be sorted in ascending order.");
assertEquals(2, list.getHead().next.value);
assertEquals(3, list.getHead().next.next.value);
assertEquals(4, list.getHead().next.next.next.value);
assertEquals(5, list.getHead().next.next.next.next.value);
assertEquals(6, list.getHead().next.next.next.next.next.value);
assertEquals(7, list.getHead().next.next.next.next.next.next.value);
assertEquals(8, list.getHead().next.next.next.next.next.next.next.value);
assertEquals(9, list.getHead().next.next.next.next.next.next.next.next.value);
assertEquals(10, list.getHead().next.next.next.next.next.next.next.next.next.value);
assertNull(list.getHead().next.next.next.next.next.next.next.next.next.next);
} }
} }