数据结构系列-------js五种常见排序方式总结和性能测试

js排序方法有很多,本文就常用的几种进行了总结,分别是快速排序,冒泡排序,插入排序,归并排序,选择排序

实例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>5种排序方式</title>
</head>

<body>
    <button onclick="sort('quick')">快速排序</button>
    <button onclick="sort('bubble')">冒泡排序</button>
    <button onclick="sort('merge')">归并排序</button>
    <button onclick="sort('insert')">插入排序</button>
    <button onclick="sort('select')">选择排序</button>
</body>
<script>
    let arrLength = 10000
    let arr = [1, 9, 28, 5, 19, 8, 27, 119, 43, 0, 4, 30, 13]
    for (let i = 0; i < arrLength; i++) {
        arr.push(Math.random(0, 1) * 10000)
    }
    console.log(arr)

    function sort(type) {
        let nowArr = [...arr]
        let newArr = []
        let startTime = new Date().getTime()
        switch (type) {
            case 'quick':
                newArr = quickSort(nowArr);
                break;
            case 'bubble':
                newArr = bubbleSort(nowArr);
                break;
            case 'merge':
                newArr = mergeSort(nowArr);
                break;
            case 'insert':
                newArr = insertSort(nowArr);
                break;
            case 'select':
                newArr = selectSort(nowArr);
                break;
        }
        let endTime = new Date().getTime()

        console.log(`${type}排序耗时${endTime - startTime}`)
        // console.log(arr)
        // console.log(newArr)
    }
    // 快速排序
    function quickSort(arr) {
        if (arr.length <= 1) {
            return arr
        }
        let centerIndex = Math.floor(arr.length / 2)
        let centerEle = arr.splice(centerIndex, 1)[0]
        let leftArr = [];
        let rightArr = [];

        for (let i = 0; i < arr.length; i++) {
            if (arr[i] < centerEle || arr[i] === centerEle) {
                leftArr.push(arr[i])
            } else {
                rightArr.push(arr[i])
            }

        }
        return quickSort(leftArr).concat([centerEle], quickSort(rightArr))
    }
    // 冒泡排序 从第一项开始与后面的每一项进行比较,如果大于后面的项就交换位置
    function bubbleSort(arr) {
        if (arr.length <= 1) {
            return arr
        }
        for (let i = 0; i < arr.length; i++) {
            // 把最大的数放到后面,较小的项逐渐向左移动
            // 数组的最后一项和前面数组中最大的交换位置
            // 第一次比较 arr.length-1  和数组最后一项
            // 第二次比较 arr.length-2 和数组倒数第二项
            // ...
            for (let j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    let tem = arr[j + 1]
                    arr[j + 1] = arr[j]
                    arr[j] = tem
                }
            }
        }
        return arr
    }
    // 归并排序(分而治之)  
    // 1.不断将数组对半分,直到每个数组只有一个
    // 2.将分出来的部分重新合并
    // 3.合并的时候按顺序排列
    function merge(left, right) {
        // debugger
        var result = [],
            left_index = 0,
            right_index = 0;

        // 将两个数组合并
        // 合并的时候按从小到大的顺序
        while (left_index < left.length && right_index < right.length) {
            if (left[left_index] < right[right_index]) {
                result.push(left[left_index++]);
            } else {
                result.push(right[right_index++]);
            }
        }

        // 和其他数组拼接
        return result.concat(left.slice(left_index)).concat(right.slice(right_index));
    }

    function mergeSort(arr) {
        // 只有一个数的时候退出递归
        if (arr.length < 2) {
            return arr;
        }

        var middle = Math.floor(arr.length / 2),
            left = arr.slice(0, middle),
            right = arr.slice(middle);

        // 递归
        // 不断拆分只到一个数组只有一个数
        return merge(mergeSort(left), mergeSort(right));
    }

    // 选择排序 在数组中找到最小的项放到数组的第一位,再找到数组中第二小的项,放到第二位,以此类推
    function selectSort(arr) {

        var len = arr.length,
            min;

        for (i = 0; i < len; i++) {

            // 将当前位置设为最小值
            min = i;

            // 检查数组其余部分是否更小
            for (j = i + 1; j < len; j++) {
                if (arr[j] < arr[min]) {
                    min = j;
                }
            }

            // 如果当前位置不是最小值,将其换为最小值
            if (i != min) {
                swap(arr, i, min);
            }
        }

        return arr;
    }
    function swap(arr, p1, p2) {
        var temp = arr[p1];
        arr[p1] = arr[p2];
        arr[p2] = temp;
    }

    // 插入排序 
    // 1.把数组分为[已排序]和[未排序]两部分, 第一个数组为[已排序],其余为[未排序]
    // 2.从[未排序]抽出第一个数,和[已排序]部分比较,插入到合适的位置

    function insertSort(arr) {
        if (arr.length <= 1) {
            return arr
        }
        var len = arr.length,     // 数组的长度
            value,                      // 当前比较的值
            i,                          // 未排序部分的当前位置
            j;                          // 已排序部分的当前位置
        for (i = 0; i < len; i++) {

            // 储存当前位置的值
            value = arr[i];

            /*
             * 当已排序部分的当前元素大于value,
             * 就将当前元素向后移一位,再将前一位与value比较
             */
            for (j = i - 1; j > -1 && arr[j] > value; j--) {
                arr[j + 1] = arr[j];
            }

            arr[j + 1] = value;
        }
        return arr;
    }
</script>

</html>

对30000个数据测试,v8引擎,结果如下

测试3次:

平均值为:

排序方式 第一次 第二次 第三次 平均值
quick 59 21 26 34.33
bubble 1690 1651 1622 1654.33
merge 69 78 92 79.66
insert 289 256 230 258.33
select 1008 991 1052 1017

数据量较大时,排序性能:quick>mrege>insert>select>bubble

参考:https://zhuanlan.zhihu.com/p/28130533

猜你喜欢

转载自blog.csdn.net/qdmoment/article/details/106083626