javascript优化插入排序算法

此次优化排序算法呢是为了在优先队列中使用这个算法。算法

我从网络上随便复制一种排序算法,随便找的,首先看看他的实现。数组

function Insertion(arr) {
    let len = arr.length;
    let preIndex, current;
    for (let i = 1; i < len; i++) {
        preIndex = i - 1;
        current = arr[i];
        while (preIndex >= 0 && current > arr[preIndex]) {
            arr[preIndex + 1] = arr[preIndex];
            preIndex--;
        }
        arr[preIndex + 1] = current;
    }
    return arr;
}
复制代码

下面是测试随机生成数组的函数:网络

function randomArr(len, start, end) {
    let arr = [];
    while (arr.length < len) {
        let d = Math.round(Math.random() * (end - start) + start);
        arr.push(d);
    }
    return arr;
}
复制代码

下面是测试函数,经过执行下面的函数能够获得对应的时间:dom

function test(n, start, end) {
    console.time();
    let a = randArr(n, start, end);
    let b = Insertion(a);
    console.timeEnd()
}
复制代码

其中n表明数组的个数,startend表明数组的开始和结束,也就是区间。函数

下面是我优化后的函数:测试

function insertSort(arr = []) {
    let sortArr = [];
    // 当数组的长度小于2的时候
    if (arr.length >= 2) {
        if (arr[0] < arr[1]) {
            sortArr.push(arr[1], arr[0]);
        } else {
            sortArr.push(arr[0], arr[1]);
        }
    } else {
        sortArr.push(...arr);
    }
    for (let i = 2; i < arr.length; i++) {
        let lPos = 0;       // 左边
        let rPos = sortArr.length; // 右边
        let j = Math.floor((rPos - lPos) / 2);
        while (rPos - lPos !== 1) {
            if (arr[i] > sortArr[j]) {
                rPos = j;
            } else if (arr[i] < sortArr[j]) {
                lPos = j;
            } else {
                lPos = j - 1;
                rPos = j;
            }
            j = Math.floor((rPos + lPos) / 2); // j的值是这二者之间的值
        }
        if (arr[i] > sortArr[j]) {          // 最后判断与j位置的值,谁大谁小
            sortArr.splice(j, 0, arr[i]);   // 大则在当前位置插入
        } else {
            sortArr.splice(j + 1, 0, arr[i]);// 小则在下一个位置插入
        }
    }
    return sortArr;
}
复制代码

函数的实现比前一种要复杂一些。整体优化的思路在于第二层。也就是在找插入位置的时候我是经过二分搜索的方式进行的,这样的时间负责度,差很少是nlogn级别的。跟前一种n^2级别要好一些,固然不能跟快速排序相提并论,之因此没有选择快速排序是由于快速排序的稳定性很差。而我要实现的优先队列对稳定性要求高。优化

下面分别是10万 - 50万的测试结果,越到后面的数据次数越少(多条测试使用的逗号隔开的)。我这样的对比并不是严格意义上的控制变量法,可是因为我执行屡次获得的结果几乎类似,因此基本上能够说明优化的效果。ui

// (100000数据量)
test(Insertion, 100000, 0, 10000); // 3.057, 3.101s, 3.072s, 3.078s
test(insertSort, 100000, 0, 10000);// 737.965ms, 764.219ms, 732.931ms, 739.714ms
复制代码
// (200000数据量)
test(Insertion, 200000, 0, 10000); // [12.464s]
test(insertSort, 200000, 0, 10000);// [4.506s]
复制代码
// (300000数据量)
test(Insertion, 300000, 0, 10000); // 27.746s,28.024s
test(insertSort, 300000, 0, 10000);// 10.432s,10.695s
复制代码
// (400000数据量)
test(Insertion, 400000, 0, 10000); // 50.283s
test(insertSort, 400000, 0, 10000);// 16.581s
复制代码
// (500000数据量)
test(Insertion, 500000, 0, 10000); // 1:18.815 (m:ss.mmm),1:19.075 (m:ss.mmm)
test(insertSort, 500000, 0, 10000);// 43.778s, 44.420s
复制代码
相关文章
相关标签/搜索