睡眠排序算法是一种比较另类有趣的排序算法,其核心思想与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
可以看到报错结果提示为非法数据异常,睡眠时间不能为负数。那么是不是负数就没办法使用睡眠排序算法呢?不是,正如我上面所说的只需要通过一定的规律把睡眠时间转换成正数即可,比如加上一个足够大的数,这个数大于等于最小负数的绝对值,那么睡眠时间就能保证为正数,但是这样还要额外写一个方法找出最小负数值,麻烦。
总结:不保证稳定,是一种通过浪费时间来达到排序目的的算法。