相信大家最近都被某位天才(bushi 写的睡眠排序刷屏了
我到想不明白这世界上怎么还有这种**
但是其实在特定环境下,睡眠排序的时间复杂度要小于冒泡sort不香是咋的
原理来说,就是给每个数字开一个进程,然后这个数字是几,就让他睡多久,数字小的先醒过来,最后结果就是一个排列好的数字串了
但是转念一想,那毕竟某场早期的睾端处理器只有4c8t AMD YES!,所以线程不是想开就开(如果有大佬搞个8路E7那就当我啥也没说)
所以我们可以只用一个线程就搞定这些事情吗
当然可以,此之谓
伪·睡眠排序算法!
废话不多说,我们直接开始讲解
#include<iostream>
using namespace std;
int main(){
return 0;
}
首先io头文件 std命名空间 int型main函数和最后返回0就不用说了
int i;
cin>>i;
int f=0;
int a[i],b[i];
for(int x=0;x<i;x++){
int c=0;
cin>>c;
if(c==0)f++;
a[x]=c;
b[x]=c;
}
定义一个变量i作为数组的成员个数 f为计数器,负责记下已处理成员个数 数组a为需排序数组,成员大小不变化,b作为备份,其中的数字为对应成员的睡眠时长
c为输入(一个顶俩),如果c为0,f就记下一个,后面会将为什么要记0的个数
for(int x=0;x<i;x++){
cout<<0<<" ";
}
现在数组里面有f个0,先将他们输出,为什么要输出还是后面讲
int x=0;
for(;;x++){
if(f==i)break;
if(b[x]!=0){
b[x]--;
if(b[x]==0){
f++;
cout<<a[x]<<" ";
}
}
if(x==i-1)x=-1;
}
定义x作为数组b下标
循环停止的标志是所有成员全部醒来,也就是用来记醒来成员数的f=成员总数i
同时每当x循环到最后一个成员但是f还未到达i时,就让x=-1,在下一次循环中x+1就变为0,也就是从第一个数字从新开始
之所以先把0排除,是因为当一个数字睡醒的时候,在循环中,这个数字-1会变为0;而0本身就为0,所以无法判断,就需要将其排除
那么完整版代码如下
#include<iostream>
using namespace std;
int main(){
int i;
cin>>i;
int f=0;
int a[i],b[i];
for(int x=0;x<i;x++){
int c=0;
cin>>c;
if(c==0)f++;
a[x]=c;
b[x]=c;
}
for(int x=0;x<i;x++){
cout<<0<<" ";
}
int x=0;
for(;;x++){
if(f==i)break;
if(b[x]!=0){
b[x]--;
if(b[x]==0){
f++;
cout<<a[x]<<" ";
}
}
if(x==i-1)x=-1;
}
return 0;
}
如有错误欢迎指正 本人邮箱 xtr0928@126.com