在原型链上实现自己的sort函数,并根据传入的函数判断升序排序还是降序

70 阅读2分钟

在原型链上实现自己的sort函数,并根据传入的函数判断升序排序还是降序

JS 中的 sort 实现

数量小于 10 的数组使用插入排序,比 10 大的数组则使用快速排序。

插入排序

通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

  1. 时间复杂度:
    • 最坏情况:O(n2)
    • 最好情况:O(n)
    • 平均情况:O(n2)
  2. 空间复杂度:O(1)
  3. 稳定性:

快速排序

通过选定一个数字作为比较值,将要排序其他数字,分为 >比较值<比较值,两个部分。并不断重复这个步骤,直到只剩要排序的数字只有本身,则排序完成。

  1. 时间复杂度:
    • 最坏情况:O(n2)
    • 最好情况:O(nlog2n)
    • 平均情况:O(nlog2n)
  2. 空间复杂度:O(nlog2n)
  3. 稳定性:

代码实现

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;
}