在原型链上实现自己的sort函数,并根据传入的函数判断升序排序还是降序
JS 中的 sort 实现
数量小于 10 的数组使用插入排序,比 10 大的数组则使用快速排序。
插入排序
通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
- 时间复杂度:
- 最坏情况:O(n2)
- 最好情况:O(n)
- 平均情况:O(n2)
- 空间复杂度:O(1)
- 稳定性: ✅
快速排序
通过选定一个数字作为比较值,将要排序其他数字,分为 >比较值 和 <比较值,两个部分。并不断重复这个步骤,直到只剩要排序的数字只有本身,则排序完成。
- 时间复杂度:
- 最坏情况:O(n2)
- 最好情况:O(nlog2n)
- 平均情况:O(nlog2n)
- 空间复杂度:O(nlog2n)
- 稳定性: ❌
代码实现
Array.prototype.mySort = function (fn) {
let arr = this;
let len = arr.length;
// 数组长度小于10,插入排序
if (len <= 10) {
for (let i = 1; i < len; i++) {
let preIndex = i - 1;
let current = arr[i];
// fn不存在,将数字会转换为字符串,对比unicode位
// fn 存在,执行fn,将结果与0做比较
while (preIndex >= 0 && (fn ? fn(arr[preIndex], current) > 0 : current.toString() < arr[preIndex].toString())) {
arr[preIndex + 1] = arr[preIndex];
--preIndex;
}
arr[preIndex + 1] = current;
}
} else {
// 快排
sort(arr, 0, len - 1);
function sort(arr, low, high) {
if (low >= high) {
return;
}
let i = low;
let j = high;
// 基准
const x = arr[i];
while (i < j) {
// 从数组尾部找到比 x 小的数字
while (arr[j] >= x && i < j) {
--j;
}
// 将比 x 大的数填入基准位置,当前位置空出
if (i < j) {
arr[i] = arr[j];
++i;
}
// 从数组头部找到比 x 大的数字
while (arr[i] <= x && i < j) {
++i;
}
if (i < j) {
arr[j] = arr[i];
--j;
}
}
// i、j相遇时的位置就是基准值该存放的正确位置
arr[i] = x;
sort(arr, low, i - 1);
sort(arr, i + 1, high);
}
}
return arr;
}