zoukankan      html  css  js  c++  java
  • 睡眠排序、面条排序、猴子排序...........................

    内容整编自多个网友的文章,外加上自己的一些感想,链接太多就不一一列举了:)

    1. 睡眠排序(Sleep Sort)

    睡眠排序也称为硬件排序, 充分利用硬件计时器的资源实现拟态算法(逃

    这个事件起源于一个屌丝发表了一个时间复杂度为O(n)的排序算法,睡眠排序的主要逻辑是构造n个线程,它们和这n个数一一对应。初始化后,线程们开始睡眠,等到对应的那么多个时间单位后各自醒来,然后输出对应的数。这样最小的数对应的线程最早醒来,这个数最早被输出。等所有线程都醒来,排序就结束了。能脑洞大开想出此算法的,绝壁天才啊。
    于是我一本正经地试着实现一下这个Idea:

    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 实现:
     

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

    算法的意义在意,它是一个“算法”。要知道算法的概念远早于计算机,我们的代码都是对“算法”的模拟,也是对自然模拟,就好像数学物理学那样...跳出计算机思维之外,很多的问题都有很直观的解法,你可以认为是有趣的思维实验;

    3. 猴子排序(Bogo Sort)

    随机打乱数组,检查是否排好序,若是,则输出,否则再次打乱,再检查...最佳情况O(n),平均O(n*n!),最坏可执行直到世界的尽头。
    算法代码主体部分基本上就是这样的:

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

    See also 无限猴子定理:一只猴子随机敲打打字机键盘,如果时间足够长,总是能打出特定的文本,比如莎士比亚全集。

    注:

    猴子那个一开始以为最好不应该是时间复杂度为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;
    }
    
  • 相关阅读:
    将后台返回的 xml replace
    程序员数学的重要性
    .net里生成的 checkboxlist 至少要选择一个
    关于如何坚持目标,网上偶然看到的,转载一下
    犹豫不决(收集)
    CSS中Padding参数说明及使用指南
    IE地址栏小图标问题
    常用sql语句集锦
    ie9怎么开兼容模式
    一台MySql服务器不同数据库之间数据同步_解决方案(Java)
  • 原文地址:https://www.cnblogs.com/xosg/p/10257768.html
Copyright © 2011-2022 走看看