Java排序 - 不實用的幾個排序算法 -- 睡眠排序、猴子排序、面條排序、珠排序


介紹幾個不實用的排序算法,一來可以在學習時增加一些樂趣,放松一下自己,二來可以學習一下、思考一下這些算法失敗在哪里,又是否存在一些好的地方?

睡眠排序

這是一個思想比較簡單,腦洞巨大的算法 -- 我們知道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     }

 

猴子排序(隨機排序)

 猴子排序引用了無限猴子定理:即一只猴子隨機不停的敲擊鍵盤,如果時間足夠長,那么它總有可能會打出特定的文本,比如莎士比亞全集?,算法通過不停的隨機排列數組,直到數組有序

    /* 判斷一個數列是否有序 */
    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));
    }

 

珠排序

我們知道,在重力的作用下,如果將算盤立起來,無論怎么撥動,算珠最終都會掉下來緊挨在一起,那如果每根柱子上的算珠個數不太一樣呢?見圖片

如圖,我們看到神奇的重力已經幫我們排好序了?那如何將此現象寫成代碼呢?我們用一個二維數組模擬整個算盤,每一個數擁有一行算珠

見代碼

 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,為了不至於手掌無處安放,我們將手直接放在最高的面條的頂端

代碼

    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;
                }
            }
        }
    }

 

 


對於這些似乎玩笑性的排序算法,除了睡眠排序,我幾乎沒有找到相關源碼,這些源碼是我嘗試着去寫的,並為其做個小總結,也是為了能給一些人做個借鑒,當然如果有地方寫的不好,或者有什么問題與意見,歡迎大家提出來

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM