Skip to content

refactor: Enhance docs, add tests in QuickSortLinkedList #5998

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 25, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -104,36 +104,52 @@

public class QuickSortLinkedList {

private SinglyLinkedList list = null; // Linked list
private Node head = null; // head of the list
// Counstructor
private final SinglyLinkedList list; // The linked list to be sorted
private Node head; // Head of the list

/**
* Constructor that initializes the QuickSortLinkedList with a given linked list.
*
* @param list The singly linked list to be sorted
*/
public QuickSortLinkedList(SinglyLinkedList list) {
this.list = list;
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() {
head = sortList(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) {
return head;
}

// Choose the first element as the pivot
Node pivot = head;
head = head.next;
pivot.next = null;

Node lessHead = new Node(); // stores the nodes cantaining data less than pivot node
Node lessTail = lessHead; // tail of lessHead
Node greaterHead = new Node(); // stores the nodes cantaining data greater than pivot node
Node greaterTail = greaterHead; // tail of greaterHead
Node lessHead = new Node();
Node lessTail = lessHead;
Node greaterHead = new Node();
Node greaterTail = greaterHead;

// Partition the list around the pivot
while (head != null) {
if (head.value < pivot.value) {
lessTail.next = head;
Expand All @@ -145,15 +161,12 @@ public Node sortList(Node head) {
head = head.next;
}

// Seperating lessHead and greaterHead to form two seperate linkedList
lessTail.next = null;
greaterTail.next = null;

// Recursively sort the sublists
Node sortedLess = sortList(lessHead.next);
Node sortedGreater = sortList(greaterHead.next);

// Combine the sorted sublists and pivot
if (sortedLess == null) {
pivot.next = sortedGreater;
return pivot;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
import static org.junit.jupiter.api.Assertions.assertNull;

import org.junit.jupiter.api.Test;

/**
* Test cases for QuickSortLinkedList
* Test cases for QuickSortLinkedList.
* Author: Prabhat-Kumar-42
* GitHub: https://github.com/Prabhat-Kumar-42
*/
Expand All @@ -16,9 +17,8 @@ public void testSortEmptyList() {
SinglyLinkedList emptyList = new SinglyLinkedList();
QuickSortLinkedList sorter = new QuickSortLinkedList(emptyList);

// Test case: Sorting an empty list should result in an empty list
sorter.sortList();
assertNull(emptyList.getHead());
assertNull(emptyList.getHead(), "Sorted empty list should have no elements.");
}

@Test
Expand All @@ -27,10 +27,51 @@ public void testSortSingleNodeList() {
singleNodeList.insert(5);
QuickSortLinkedList sorter = new QuickSortLinkedList(singleNodeList);

// Test case: Sorting a list with a single node should result in the same list
sorter.sortList();
assertEquals(5, singleNodeList.getHead().value);
assertNull(singleNodeList.getHead().next);
assertEquals(5, singleNodeList.getHead().value, "Single node list should remain unchanged after sorting.");
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
Expand All @@ -48,18 +89,7 @@ public void testSortMultipleElementsList() {
list.insert(6);
QuickSortLinkedList sorter = new QuickSortLinkedList(list);

// Test case: Sorting a list with multiple elements
sorter.sortList();
assertEquals(1, list.getHead().value);
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);
assertEquals("1->2->3->4->5->6->7->8->9->10", list.toString(), "List should be sorted in ascending order.");
}
}