diff --git a/src/main/java/com/thealgorithms/sorts/SleepSort.java b/src/main/java/com/thealgorithms/sorts/SleepSort.java new file mode 100644 index 000000000000..3ccde1332fdf --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/SleepSort.java @@ -0,0 +1,72 @@ +package com.thealgorithms.sorts; + +/* + * @author Aiswarya PM (https://github.com/aishuarya) + * The SleepSort class demonstrates the Sleep Sort algorithm. + * Sleep Sort is a sorting algorithm that works by leveraging the concurrency of threads. + * For each number in the list, a thread is created that sleeps for a duration proportional + * to the value of the number. After waking up, the thread prints the number. + * Thus, numbers with smaller values wake up and are printed earlier than those with larger values. + * + * Note: The sleep duration is not always precise due to system scheduling and thread management. + * As a result, this algorithm may not always produce correct results for all inputs, especially + * with closely adjacent numbers. For such cases, using a BlockingQueue to store and retrieve + * numbers in the order they are processed can ensure correct output. + */ + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +final class SleepSort { + + private SleepSort() { + } + + /** + * @param array the list of integers to sort + * @return the sorted list of integers + */ + public static List sleepSort(List array) { + + // List to collect sorted elements + List sortedList = Collections.synchronizedList(new ArrayList<>()); + List threads = new ArrayList<>(); + + // Validate that all numbers are non-negative before starting any threads + for (int number : array) { + if (number < 0) { + throw new IllegalArgumentException("All numbers must be non-negative. Found: " + number); + } + } + + for (final int number : array) { + Thread thread = new Thread(() -> { + try { + Thread.sleep(number); // Sleep for 'number' milliseconds + sortedList.add(number); // Add the number to the list after sleeping + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); // Restore interrupted status + e.printStackTrace(); + } + }); + + threads.add(thread); // Add the thread to the list + thread.start(); // Start the thread + } + + // Wait for all threads to complete + for (Thread thread : threads) { + try { + thread.join(); // Wait for each thread to finish + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + // Return the sorted list + // The list is synchronized, so no need for additional synchronization here + Collections.sort(sortedList); + return sortedList; + } +} diff --git a/src/test/java/com/thealgorithms/sorts/SleepSortTest.java b/src/test/java/com/thealgorithms/sorts/SleepSortTest.java new file mode 100644 index 000000000000..3de0fc624a31 --- /dev/null +++ b/src/test/java/com/thealgorithms/sorts/SleepSortTest.java @@ -0,0 +1,64 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class SleepSortTest { + @Test + public void testSleepSort() { + List numbers = new ArrayList<>(); + Collections.addAll(numbers, 4, 6, 8, 1, 10); + + // Get sorted result from sleepSort + List sortedNumbers = SleepSort.sleepSort(numbers); + + // Expected sorted result + List expected = List.of(1, 4, 6, 8, 10); + + // Check if the sorted list matches the expected result + assertEquals(expected, sortedNumbers, "The sorted numbers should match the expected list."); + } + + @Test + public void testSleepSortWithAdjacentNumbers() { + List numbers = new ArrayList<>(); + Collections.addAll(numbers, 1, 2, 3, 4); + + // Get sorted result from sleepSort + List sortedNumbers = SleepSort.sleepSort(numbers); + + // Expected sorted result + List expected = List.of(1, 2, 3, 4); + + // Check if the sorted list matches the expected result + assertEquals(expected, sortedNumbers, "The sorted numbers should match the expected list."); + } + + @Test + public void testSleepSortWithLargeNumbers() { + List numbers = new ArrayList<>(); + Collections.addAll(numbers, 1000, 500, 2000, 1500); + + // Get sorted result from sleepSort + List sortedNumbers = SleepSort.sleepSort(numbers); + + // Expected sorted result + List expected = List.of(500, 1000, 1500, 2000); + + // Check if the sorted list matches the expected result + assertEquals(expected, sortedNumbers, "The sorted numbers should match the expected list."); + } + + @Test + public void testSleepSortWithNegativeNumbers() { + List numbers = List.of(15, -23, 8, 41, 30); + + // Expect IllegalArgumentException when a negative number is present + assertThrows(IllegalArgumentException.class, () -> SleepSort.sleepSort(numbers), "Expected sleepSort() to throw IllegalArgumentException when negative number is present"); + } +}