睡眠排序演算法是一種比較另類有趣的排序演算法,其核心思想與CPU排程機制相關,是通過多執行緒讓每一個資料元素睡眠一定規律的時間,睡眠時間要和自身資料大小存在一定的規律,睡眠時間短的先進行輸出,睡眠長的後輸出,從而實現資料有序輸出。
存在缺點:
①若睡眠時間之間相差很小時,容易出現誤差,為了減小誤差,一般需要放大睡眠倍數;
②因為睡眠時間和資料大小有直接關係,因此資料不能太大 ,若資料很大時,睡眠時間要很久,程式執行時間很長;
③睡眠時間不能為負數,如果排序資料中存在負數,需要按照一定的規律把對應的睡眠時間轉換成正數,比如說在設定睡眠時間時,把每一項都加上一個正數(該正數的絕對值要比最小負數的絕對值要打)。
程式碼實現:
public class SleepSort { public static class sleepthread extends Thread{ private int num; public sleepthread(int num){ this.num=num; } @Override public void run() { try { //放大睡眠時間:為了減小誤差,如果資料大小比較相近,睡眠時間較短就容易出現誤差 sleep(num*10); } catch (Exception e) { e.printStackTrace(); } System.out.print(num+" "); } } public static void main(String[] args) { int num[]= {5,22,10,7,59,3,16,4,11,8,14,24,27,25,26,28,23,99}; System.out.print(" 原始資料排列:"); for(int i:num) { System.out.print(i+" "); } System.out.print("\n排序後資料排列:"); sleepthread array[]=new sleepthread[num.length]; for(int i=0;i<array.length;i++) { array[i]=new sleepthread(num[i]); array[i].start(); } } }
執行結果:
原始資料排列:5 22 10 7 59 3 16 4 11 8 14 24 27 25 26 28 23 99
排序後資料排列:3 4 5 7 8 10 11 14 16 22 23 24 25 26 27 28 59 99
①把睡眠時間設定為num,即sleep(num),對資料項 num[]= {2,1,5,4,3,7,9,8,6}進行睡眠排序,結果如下所示:
原始資料排列:2 1 5 4 3 7 9 8 6
排序後資料排列:1 2 3 5 4 6 7 8 9
可以看出當睡眠時間差值很小時並不能保證排序結果正確。
②在睡眠時間為sleep(num*10)的基礎上,對資料項num[]= {2,1,5,4,3,7,9,8,6,9999};進行睡眠排序,其結果如下所示
原始資料排列:2 1 5 4 3 7 9 8 6 9999
排序後資料排列:1 2 3 4 5 6 7 8 9
可以看到9999並沒有馬上出現,sleep(num*10),即睡眠時間為99.99秒,如果再多幾個這麼大的數字,那麼真的是等得花兒都謝了。
③在資料項中插入負數元素,如:num[]= {2,1,5,4,-3,7,9,8,6,10};,執行結果如下所示
原始資料排列:2 1 5 4 -3 7 9 8 6 10
排序後資料排列:
-3 java.lang.IllegalArgumentException: timeout value is negative
at java.lang.Thread.sleep(Native Method)
at SleepSort$sleepthread.run(SleepSort.java:12)
1 2 4 5 6 7 8 9 10
可以看到報錯結果提示為非法資料異常,睡眠時間不能為負數。那麼是不是負數就沒辦法使用睡眠排序演算法呢?不是,正如我上面所說的只需要通過一定的規律把睡眠時間轉換成正數即可,比如加上一個足夠大的數,這個數大於等於最小負數的絕對值,那麼睡眠時間就能保證為正數,但是這樣還要額外寫一個方法找出最小負數值,麻煩。
總結:不保證穩定,是一種通過浪費時間來達到排序目的的演算法。