睡眠排列
-
睡眠排序算法是一种比较另类有趣的排序算法,通过多线程让每一个数据元素睡眠一定规律的时间,睡眠时间要和自身数据大小存在一定的规律,睡眠时间短的先进行输出,睡眠长的后输出,从而实现数据有序输出。
-
存在缺点:
- 若睡眠时间之间相差很小时,容易出现误差,为了减小误差,一般需要放大睡眠倍数;
- 因为睡眠时间和数据大小有直接关系,因此数据不能太大 ,若数据很大时,睡眠时间要很久,程序运行时间很长;
- 睡眠时间不能为负数,如果排序数据中存在负数,需要按照一定的规律把对应的睡眠时间转换成正数,比如说在设置睡眠时间时,把每一项都加上一个正数(该正数的绝对值要比最小负数的绝对值要大)。
-
预期实现
原始数据排列:5 22 10 7 59 3 16 4 11 8 14 24 27 25 26 28 23 99
排序后数据排列:3 4 5 7 8 10 11 14 16 22 23 24 25 26 27 28 59 99
有一个需求:
在一个 js 文件中提供一个类,拥有如下功能:
- 异步静态方法 sleep():
- 参数为 timeout,返回值为 Promise< void >。
- 封装 setTimeout,实现调用 await sleep(timeout) 能让当前方法等待 timeout 毫秒后再继续执行。
- 如果参数不为数字或不为 undefined,抛出合适的异常。
- 异步静态方法 sleepSort():
- 参数为 Array < number >,返回值为 Array < number >。
- 实现对数组的睡眠排序 (每个数字均为不大于 1000 的正整数)。
不能直接使用 setTimeout,而是使用已有的 sleep() 函数。
使用 Promise.all(),打印一下数组中各数据对应的排序位置:Promise< Array < number> >
在 index.js 中引用这个类,在 run() 方法中随机生成 100 个不大于 1000 的正整数,通过这个类的 sleepSort() 排序,并返回结果。
解决方案
在同目录下创建 index.js 和 TimeHelper.js 文件。
index.js :
import TimeHelper from './TimeHelper.js';
const t = new TimeHelper();
const run = async () => {
try {
const number = [];
for (let i = 0; i < 100; i++) {
number.push(Math.round(Math.random() * 1000));
}
const result = await t.sleepSort(number);
console.log(result);
} catch (error) {
console.error('error', error);
}
};
run();
TimeHelper.js :
export default class TimeHelper {
res = [];
sleep(timeout) {
this.timeout = timeout;
if (typeof timeout === 'number' || typeof timeout === 'undefined') {
return new Promise((resolve) => {
setTimeout(() => {
resolve(this.res.push(timeout));
}, timeout);
});
} return Promise.reject(new Error('Wrong parameter type'));
}
async sleepSort(arr) {
console.log(arr);
const promiseArr = [];
arr.forEach(num => {
promiseArr.push(this.sleep(num));
});
const promiseResArr = await Promise.all(promiseArr);
console.log(promiseResArr);
return this.res;
}
}
运行结果
- node index.js 运行 index 文件,数组也可按需更改成自己想要的数组。
- 原数组数据
- 原数组各数据对应的顺序
- 排序完成的数组
- 原数组数据