睡眠排序、麪條排序、猴子排序...........................

內容整編自多個網友的文章,外加上本身的一些感想,連接太多就不一一列舉了:)javascript

1. 睡眠排序(Sleep Sort)

睡眠排序也稱爲硬件排序, 充分利用硬件計時器的資源實現擬態算法(逃java

這個事件起源於一個屌絲髮表了一個時間複雜度爲O(n)的排序算法,睡眠排序的主要邏輯是構造n個線程,它們和這n個數一一對應。初始化後,線程們開始睡眠,等到對應的那麼多個時間單位後各自醒來,而後輸出對應的數。這樣最小的數對應的線程最先醒來,這個數最先被輸出。等全部線程都醒來,排序就結束了。能腦洞大開想出此算法的,絕壁天才啊。
因而我一本正經地試着實現一下這個Idea:ios

public class SleepSort {
    public static void main(String[] args){
        int[] nums={9,7,2,6,15,8,9,9,9,9,9};
        SleepSort.sort(nums);
        for(int n:nums)
            System.out.printf("%d   ",n);
    }
    public static void sort(int[] nums){
        Sleeper.idx=0;
        Sleeper.output=new int[nums.length];
        for(int i=0;i<nums.length;i++)        //[1]
            new Sleeper(nums[i]).start();
        
        for(int i=0;i<nums.length;i++)
            nums[i]=Sleeper.output[i];
    }
}
class Sleeper extends Thread{
    public static int[] output;
    public static int idx;
    private int sleep_time;
    public Sleeper(){
        this.sleep_time=0;
    }
    public Sleeper(int sleep_time){
        this.sleep_time=sleep_time;
    }
    @Override
    public void run(){
        try{
            Thread.sleep(this.sleep_time);
        }catch(InterruptedException e){
            e.printStackTrace();
        }
        output[idx++]=this.sleep_time;
    }
}

 

固然也能夠用我大javascript setTimeout 實現:
 c++

let nums = [9,7,2,6,15,8,9,9,9,9,9]
, output = []

nums.forEach(function (num) {
setTimeout(function () {
output.push(num)
if (output.length == nums.length) {
console.log(output)
}
}, num)
})

算法其實真的很天才,讓操做系統來處理排序的複雜度,並且很容易並行起來...不過最大的做用還開腦洞吧;算法

2. 麪條排序(Spaghetti Sort, 意麪排序)

首先去買一捆面,是意麪掛麪仍是手擀麪請按我的口味決定,最好是硬的。找到數組中最大和最小的兩個數(O(n)),讓最大的數對應一根很長的麪條,最小的數對應一根很短的麪條。從新遍歷數組,每遇到一個數,就取一根麪條,把它切成這個數對應的長度,能夠獲得n根麪條。這裏的數與麪條長度的對應能夠用一個嚴格遞增的函數來映射。接下來,一手握住這n根麪條,稍微用力,別握太緊,在平放的桌面上直立着放下,讓全部的麪條底端接觸到桌面。另外一隻手平行於桌面,從麪條上方緩慢往下移動,每當這隻手碰到一根麪條,移走它,並把對應的數輸出到結果數組中,直到移走所有面條。
用完的麪條還能夠煮夜宵哦。
麪條排序的思想基本上跟睡眠排序同樣樣的,公佈程序數組

#include<iostream>
using namespace std;
int main()
{
int g;
cin>>g;
int a[g],count=0,i,ai;
for (i=0;i<g;i++)
cin>>a[i];
for (i=0;i<g;i++)
{
for (ai=0;i<g;i++)
{
a[ai]--;
if(a[ai]==0)
cout>>count+1;
}
count++;
}
return 0;
}

算法的意義在乎,它是一個「算法」。要知道算法的概念遠早於計算機,咱們的代碼都是對「算法」的模擬,也是對天然模擬,就好像數學物理學那樣...跳出計算機思惟以外,不少的問題都有很直觀的解法,你能夠認爲是有趣的思惟實驗;ide

 

3. 猴子排序(Bogo Sort)

隨機打亂數組,檢查是否排好序,如果,則輸出,不然再次打亂,再檢查...最佳狀況O(n),平均O(n*n!),最壞可執行直到世界的盡頭。
算法代碼主體部分基本上就是這樣的:函數

while(! isOrdered(nums))
    shuffle(nums);

See also 無限猴子定理:一隻猴子隨機敲打打字機鍵盤,若是時間足夠長,老是能打出特定的文本,好比莎士比亞全集。this

注:spa

猴子那個一開始覺得最好不該該是時間複雜度爲1,因一次瞎排就得出結果. 但還得查看是否有序,這個過程耗的時,這是那個n

第三個算法,最大的意義也許在於觀衆看完以後的那句「臥槽這也行」、「這特麼什麼鬼」...-_-||

完整代碼(c++):

#include <iostream>
using namespace std;
int source[10],flag[10],res[10];
int sort(){
    memset(flag,1,sizeof(flag));
    int num = 10,count=0;
    while(num){
        int t =rand()%10;   //生成0-9之間的數
        if(flag[t]){
            res[count++] = source[t];
            num--;
        }
    }
    for(int i=0;i<9;i++){
        if(res[i]>res[i+1]){      //只有是從小到大的排列才行
            return 0;
        } 
    }
    return 1;
}
int main(){
    int count = 0;
    for(int i=0;i<10;i++){
        cin>>source[i];
    }
    while(sort()!=1){
        count++;
    }
    cout<<"共運行了"<<count<<"次"<<endl;
    return 0;
}
相關文章
相關標籤/搜索