介绍几个不实用的排序算法,一来能够在学习时增长一些乐趣,放松一下本身,二来能够学习一下、思考一下这些算法失败在哪里,又是否存在一些好的地方?算法
这是一个思想比较简单,脑洞巨大的算法 -- 咱们知道sleep方法可让一个线程睡眠s毫秒,若是须要对一个有n个数的数列进行排序,咱们何不为每一个数建立一个线程,而后让每一个线程都睡眠该数的时间,那么对于越小的数,其睡眠时间越短,越大的数,其睡眠时间越长,最后就使得全部元素完成“排序”了数组
1 public void sleepSort(int[] arr){ 2 3 /** 建立线程类 */ 4 class Slee extends Thread{ 5 6 private int time; 7 8 public Slee(int time){ 9 this.time=time; 10 } 11 12 public void run(){ 13 try { 14 /* 由于毫秒时间过短 若是两个数相差比较小 完成不了排序 建议乘一个系数 好比10 */ 15 Thread.sleep(time*10); 16 } catch (InterruptedException e) { 17 e.printStackTrace(); 18 } 19 System.out.print(time+", "); 20 } 21 } 22 23 /* 排序 */ 24 for (int i = 0; i < arr.length; i++) { 25 new Slee(arr[i]).start(); 26 } 27 }
猴子排序引用了无限猴子定理:即一只猴子随机不停的敲击键盘,若是时间足够长,那么它总有可能会打出特定的文本,好比莎士比亚全集?,算法经过不停的随机排列数组,直到数组有序dom
/* 判断一个数列是否有序 */ public boolean isSort(int[] arr){ for (int i = 0; i < arr.length-1; i++) { if(arr[i+1]<arr[i]){ return false; } } return true; } public void monkeySort(int[] arr){ int count=0; Random random=new Random(); do{ /* 从待排序数组右边随机抽取一位数与左边进行交换*/ for (int i = 0; i < arr.length-1; i++) { count++; int t=(random.nextInt(arr.length-i)+i); int tmp=arr[i]; arr[i]=arr[t]; arr[t]=tmp; } }while(!isSort(arr)); System.out.println(count+" "+Arrays.toString(arr)); }
咱们知道,在重力的做用下,若是将算盘立起来,不管怎么拨动,算珠最终都会掉下来紧挨在一块儿,那若是每根柱子上的算珠个数不太同样呢?见图片学习
如图,咱们看到神奇的重力已经帮咱们排好序了?那如何将此现象写成代码呢?咱们用一个二维数组模拟整个算盘,每个数拥有一行算珠this
见代码spa
1 /* 2 * 一串串珠子 以下 最上面的珠子会往下掉 变成下图 3 * ******** * 4 * **** | ** 5 * ****** \|/ **** 6 * ** . ****** 7 * * ******** 8 * 用二位数组将数字模拟成珠子 9 */ 10 public void pearlSort(int[] arr) { 11 int min=arr[0]; 12 int max=arr[0]; 13 for (int i = 0; i < arr.length; i++) { 14 if(min>arr[i]) { 15 min=arr[i]; 16 } 17 if(max<arr[i]) { 18 max=arr[i]; 19 } 20 } 21 22 /* 23 * 定义二维数组 24 */ 25 int[][] pal=new int[arr.length][max-min+1]; 26 /* 27 * 给二维数组串上珠子 28 */ 29 for (int i = 0; i < pal.length; i++) { 30 for (int j = 0; j < arr[i]-min; j++) { 31 pal[i][j]=1; 32 } 33 pal[i][pal[i].length-1]=arr[i]; 34 } 35 36 /* 37 * 珠子往下落 38 */ 39 for (int i = 0; i < pal.length; i++) { 40 for (int v = pal.length-1-i; v > 0; v--) { 41 for (int j = 0; j < pal[v].length-1; j++) { 42 if(pal[v][j]!=0&&pal[v-1][j]==0) { 43 pal[v][j]=0; 44 pal[v][pal[v].length-1]--; 45 pal[v-1][j]=1; 46 pal[v-1][pal[v].length-1]++; 47 } 48 } 49 } 50 /* 51 * 依次将剩余的最大值赋给原数组 52 */ 53 arr[arr.length-1-i]=pal[i][pal[i].length-1]; 54 } 55 }
若是桌子上有一把长短不一的面条,此时你将面条立起来,下端平放在桌面上,此时你用手掌在空中从上往下缓慢移动,慢慢的,你的手掌触碰到了一根面条(这根面条是最高的),你将这根面条抽走(抽走的面条固然想怎么吃就怎么吃),手继续慢慢向下移动,这是,你又碰到了倒数第二高的面条,你又将其抽走,。。。。线程
算法中,咱们用一个数模拟手,每次-1,为了避免至于手掌无处安放,咱们将手直接放在最高的面条的顶端code
代码blog
public void noodleSort(int[] arr) { /** 模拟手 */ int hand=arr[0]; /** 获取最小值 模拟桌子 防止手一直运动*/ int min=arr[0]; /** 将最大值赋给变量 */ for (int i = 0; i < arr.length; i++) { if(hand<arr[i]) { hand=arr[i]; } if(min>arr[i]) { min=arr[i]; } } for (int i = arr.length-1; hand>=min; hand--) { for (int j = 0; j <= i; j++) { if(hand==arr[j]) { /** j为何要-- 防止交换的数字自己也等于hand */ arr[j--]=arr[i]; arr[i--]=hand; } } } }
对于这些彷佛玩笑性的排序算法,除了睡眠排序,我几乎没有找到相关源码,这些源码是我尝试着去写的,并为其作个小总结,也是为了能给一些人作个借鉴,固然若是有地方写的很差,或者有什么问题与意见,欢迎你们提出来排序