猴子排序
不知道小伙伴们一看到这个标题时是啥感觉呢,我刚看到时心里一惊,难道是让猴子来进行排序!了解了它的原理后,发现这个名字还是挺贴切的。其实它还有一个更官方的名字——随机排序!
随机排序原理,且听我慢慢道来!
这种排序被称为最原始和最低效率的排序算法,因为它可能让你永远无法得到结果。因此在实际中不被使用,只供大家娱乐!
原理:现有一组未排序数据和相同数量的方格,然后依次随机地取出数据随机地放入方格中,直到把方格放满即止。
之所以又被称为猴子排序,我的猜测是因为。将这种随机的特性利用猴子来形容,毕竟猴子并不懂数的大小,让猴子选择和放置数据肯定就是随机的了!
是不是觉得很无语呢,这尼玛也是排序。不过再看其实它还是能达到我们想要的排序效果的,虽然概率很小(数据比较多的时候)。既然能解决问题,被称为方法也是无可厚非。
下面使用该方法来进行仿真实现:
代码如下:
#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;//时间测试,start和end
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;
}
这是9个数据的结果,设置成5,6,7,8时都能较快输出结果。但是当我改成10个数据之后就始终无法输出结果了,应该跟c语言的随机函数的原理有关(并不是真正随机,而是按一个具有很大周期循环,以后会介绍一下随机数生成的算法),当然同时跟我们算法也有关系了。
如果对上图的index不明白的,可以看下图
因此,如果能随机得到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
转载于:https://blog.51cto.com/zjd1988/1340641