注意:以下排序不要用於生產環境
睡眠排序(Sleep Sort)是一個非常有趣且奇特的排序演演算法,第一次看到就大吃一驚。睡眠排序並不是一個實際可用於大規模資料排序的演演算法,而更像是一種程式設計趣味或者電腦科學的玩笑。原理基於多執行緒和睡眠的概念,不是傳統的比較排序演演算法。
睡眠排序的主要思想是將待排序的一組整數分配給多個執行緒,每個執行緒負責處理一個整數,它們根據整數的值來設定睡眠時間。整數越小,睡眠時間越短,整數越大,睡眠時間越長。當所有執行緒都完成睡眠後,它們按照睡眠時間的長短排列,從而實現排序。
主要思路:
限制:
import java.util.Random;
import java.util.concurrent.CountDownLatch;
public class SleepSort {
public static void main(String[] args) throws InterruptedException {
int count = 100;
int[] nums = new int[count];
Random random = new Random();
// 限制程式不要過早中斷
CountDownLatch countDownLatch = new CountDownLatch(count);
// 隨機 100 個 1 - (10 * count) 的數
for (int i = 0; i < count; i++) {
nums[i] = random.nextInt(1, 10 * count);
}
// 開啟虛擬執行緒,延遲一定時間後列印數位
for (int i = 0; i < count; i++) {
int num = nums[i];
Thread.startVirtualThread(() -> {
try {
Thread.sleep(10L * num);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(num);
countDownLatch.countDown();
});
}
countDownLatch.await();
}
}
隨機排序,也稱為亂序排序(Random Sort)、洗牌排序(Shuffle Sort)或猴子排序(Monkey Sort),特點是將待排序的元素隨機排列。
主要思路:
限制:
import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
public class RandomSort {
public static void main(String[] args) throws InterruptedException {
// 這個數建議不要太大,不然要隨機好久
int count = 5;
Random random = new Random();
// 限制主執行緒不要退出
CountDownLatch countDownLatch = new CountDownLatch(1);
int[] nums = new int[count];
for (int i = 0; i < count; i++) {
nums[i] = random.nextInt(10);
}
int[] sortedNums = Arrays.copyOf(nums, nums.length);
// 這裡偷懶直接用sort方法,然後在下面直接判斷
Arrays.sort(sortedNums);
long startTime = System.currentTimeMillis();
// 這裡開一百萬個虛擬執行緒隨機
for (int i = 0; i < 1000000; i++) {
Thread.startVirtualThread(() -> {
while (countDownLatch.getCount() > 0){
int[] tmp = new int[count];
for (int j = 0; j < count; j++) {
tmp[j] = random.nextInt(10);
}
// 可以列印中間過程的輸出
// System.out.println(Arrays.toString(tmp));
if (Arrays.equals(sortedNums, tmp)){
System.out.println("排序完畢:未排序資料" + Arrays.toString(nums));
System.out.println("排序完畢:已排序資料" + Arrays.toString(tmp));
countDownLatch.countDown();
break;
}
}
});
}
countDownLatch.await();
// 計算總時間
System.out.println(System.currentTimeMillis() - startTime);
}
}
這兩個排序演演算法可以說是排序演演算法界的臥龍鳳雛,建議大家還是不要在生產環境使用。