Java排序 - 不实用的几个排序算法 -- 睡眠排序、猴子排序、面条排序、珠排序...
介紹幾個不實用的排序算法,一來可以在學(xué)習(xí)時增加一些樂趣,放松一下自己,二來可以學(xué)習(xí)一下、思考一下這些算法失敗在哪里,又是否存在一些好的地方?
睡眠排序
這是一個思想比較簡單,腦洞巨大的算法 -- 我們知道sleep方法可以讓一個線程睡眠s毫秒,如果需要對一個有n個數(shù)的數(shù)列進行排序,我們何不為每個數(shù)創(chuàng)建一個線程,然后讓每個線程都睡眠該數(shù)的時間,那么對于越小的數(shù),其睡眠時間越短,越大的數(shù),其睡眠時間越長,最后就使得所有元素完成“排序”了
1 public void sleepSort(int[] arr){ 2 3 /** 創(chuàng)建線程類 */ 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 /* 因為毫秒時間太短 如果兩個數(shù)相差比較小 完成不了排序 建議乘一個系數(shù) 比如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 }?
猴子排序(隨機排序)
?猴子排序引用了無限猴子定理:即一只猴子隨機不停的敲擊鍵盤,如果時間足夠長,那么它總有可能會打出特定的文本,比如莎士比亞全集?,算法通過不停的隨機排列數(shù)組,直到數(shù)組有序
/* 判斷一個數(shù)列是否有序 */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{/* 從待排序數(shù)組右邊隨機抽取一位數(shù)與左邊進行交換*/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));}?
珠排序
我們知道,在重力的作用下,如果將算盤立起來,無論怎么撥動,算珠最終都會掉下來緊挨在一起,那如果每根柱子上的算珠個數(shù)不太一樣呢?見圖片
如圖,我們看到神奇的重力已經(jīng)幫我們排好序了?那如何將此現(xiàn)象寫成代碼呢?我們用一個二維數(shù)組模擬整個算盤,每一個數(shù)擁有一行算珠
見代碼
1 /* 2 * 一串串珠子 如下 最上面的珠子會往下掉 變成下圖 3 * ******** * 4 * **** | ** 5 * ****** \|/ **** 6 * ** . ****** 7 * * ******** 8 * 用二位數(shù)組將數(shù)字模擬成珠子 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 * 定義二維數(shù)組 24 */ 25 int[][] pal=new int[arr.length][max-min+1]; 26 /* 27 * 給二維數(shù)組串上珠子 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 * 依次將剩余的最大值賦給原數(shù)組 52 */ 53 arr[arr.length-1-i]=pal[i][pal[i].length-1]; 54 } 55 }?
面條排序
如果桌子上有一把長短不一的面條,此時你將面條立起來,下端平放在桌面上,此時你用手掌在空中從上往下緩慢移動,慢慢的,你的手掌觸碰到了一根面條(這根面條是最高的),你將這根面條抽走(抽走的面條當(dāng)然想怎么吃就怎么吃),手繼續(xù)慢慢向下移動,這是,你又碰到了倒數(shù)第二高的面條,你又將其抽走,。。。。
?算法中,我們用一個數(shù)模擬手,每次-1,為了不至于手掌無處安放,我們將手直接放在最高的面條的頂端
代碼
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為什么要-- 防止交換的數(shù)字本身也等于hand */arr[j--]=arr[i];arr[i--]=hand;}}}}?
?
對于這些似乎玩笑性的排序算法,除了睡眠排序,我?guī)缀鯖]有找到相關(guān)源碼,這些源碼是我嘗試著去寫的,并為其做個小總結(jié),也是為了能給一些人做個借鑒,當(dāng)然如果有地方寫的不好,或者有什么問題與意見,歡迎大家提出來
?
轉(zhuǎn)載于:https://www.cnblogs.com/wangbingc/p/10205560.html
總結(jié)
以上是生活随笔為你收集整理的Java排序 - 不实用的几个排序算法 -- 睡眠排序、猴子排序、面条排序、珠排序...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ansible-playbook剧本使用
- 下一篇: 自动化运维之PSSH