猴子排序

不知道小伙伴们一看到这个标题时是啥感觉呢,我刚看到时心里一惊,难道是让猴子来进行排序!了解了它的原理后,发现这个名字还是挺贴切的。其实它还有一个更官方的名字——随机排序!

随机排序原理,且听我慢慢道来!

这种排序被称为最原始和最低效率的排序算法,因为它可能让你永远无法得到结果。因此在实际中不被使用,只供大家娱乐!

原理:现有一组未排序数据和相同数量的方格,然后依次随机地取出数据随机地放入方格中,直到把方格放满即止。

之所以又被称为猴子排序,我的猜测是因为。将这种随机的特性利用猴子来形容,毕竟猴子并不懂数的大小,让猴子选择和放置数据肯定就是随机的了!


是不是觉得很无语呢,这尼玛也是排序。不过再看其实它还是能达到我们想要的排序效果的,虽然概率很小(数据比较多的时候)。既然能解决问题,被称为方法也是无可厚非。



下面使用该方法来进行仿真实现:


代码如下:


#include<stdio.h>

#include<stdlib.h>

#include<time.h>


#define NUM 9

intsort_data[NUM];


voidmix_data(int *index,int num);//获得随机的排列

voidbogo_sort(int *data,int num);

int main(void)

{

      int i;

      clock_t start,end;//时间测试,startend


      for(i=0;i<NUM;i++)

      {

             sort_data[i]=rand();

      }


      start=clock();//计时开始


      bogo_sort(sort_data,NUM);


      end=clock();//计时结束


      printf("elapse time is%d",end-start);

      return 0;

}


voidmix_data(int *index,int num)//得到随机索引数组

{

      int i,j;

      int temp;

      int *flag;

      int flag_random=0;

      flag=(int *)malloc(sizeof(int)*num);

      for(i=0;i<num;i++)

      {

             flag[i]=-1;

      }


      i=0;

      while(1)

      {


             temp=rand()%num;

             if(-1==flag[temp])

             {

                    flag[temp]=temp;

                    index[i]=temp;

                    i++;

             }

             for(j=0;j<num;j++)

             {

                    if(j!=flag[j])

                           break;

             }

             if(num==j)

                    break;

      }


}


void bogo_sort(int*data,int num)

{

      int *index;

      int i;

      int flag=0;


      if(1==num)

             return;

      index=(int *)malloc(sizeof(int)*num);


      for(i=0;i<num;i++)//只是对索引数组的排序,不移动原来的数据

      {

             index[i]=-1;

      }

      while(1)

      {

             mix_data(index,num);

             for(i=1;i<num;i++)

             {

                    if( data[index[i]] <data[index[i-1]] )

                    {

                           break;

                    }


             }

             if(i==num)

                    break;

      }


      for(i=0;i<num;i++)//输出排序后的数组

      {

             printf("%d\n",data[index[i]]);

      }


      free(index);

      index=NULL;


}

201743944.jpg


这是9个数据的结果,设置成5,678时都能较快输出结果。但是当我改成10个数据之后就始终无法输出结果了,应该跟c语言的随机函数的原理有关(并不是真正随机,而是按一个具有很大周期循环,以后会介绍一下随机数生成的算法),当然同时跟我们算法也有关系了。

如果对上图的index不明白的,可以看下图


201823382.jpg


因此,如果能随机得到index数组为1,0,3,2此时完成排序了!


如果看着程序中的随机算法太麻烦,可以用matlab仿真一下(我记得有现成的函数,生成指定范围的随机排列,好像是randperm),看下效果就好!

Matlab代码

num=5;

flag=0;

sort_data=int32(65536*rand(1,num));

sorted_data=sort(sort_data);

for i=1:num

   temp=(sorted_data(i)==sort_data);

   index_gen(i)=find(temp==1);

end

while(1)

   index=randperm(num);

if index_gen==index

for j=1:num

           sort_data(index(j))

end

break;

end

end