算法基础-JS数组排序

230 阅读2分钟

多种方式

排序算法时间复杂度最好的情况最坏的情况空间复杂度排序方式稳定性
冒泡排序O(n2)O(n)O(n2)O(1)In-place稳定
选择排序O(n2)O(n2)O(n2)O(1)In-place不稳定
插入排序O(n2)O(n)O(n2)O(1)In-place稳定
希尔排序O(nlogn)O(nlognlogn)O(nlognlogn)O(1)In-place不稳定
归并排序O(nlogn)O(nlogn)O(nlogn)O(n)Out-place稳定
快速排序O(nlogn)O(nlogn)O(n2)O(logn)In-place不稳定
堆排序O(nlogn)O(nlogn)O(nlogn)O(1)In-place不稳定
计数排序O(n+k)O(n+k)O(n+k)O(k)Out-place稳定
桶排序O(n+k)O(n+k)O(n2)O(n+k)Out-place稳定
基数排序O(n*k)O(n*k)O(n*k)O(n+k)Out-place稳定

一、冒泡排序

原理:

  1. 比较相邻元素,arr[i] > arr[i + 1]两者交换位置
  2. 完成一次循环后,最大的元素会排在最后
  3. 随着每轮的比较,越来越少的元素重复上面的步骤(每轮都会选出本次最大数),直到没有任何一对数字需要比较
function bubbleSort(arr) {
    for(let i = 0, end = arr.length - 1 ; i < end; i++) {
        for(let j = 0; j < end - i; j++) {
            if(arr[j] > arr[j + 1]) {
                [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
            }
        }
    }
    return arr;
}

二、插入排序

原理:
将当前元素插入到已经排好顺序的数组中。例如i = 2时,前面2位一定是排好顺序的,则我们需要把 i = 2的元素插入到前面2项中

function insertSort(arr) {
    for(let 1 = 1, end = arr.length - 1; i <= end; i++) {
        let cur = arr[i];
        let p = i - 1;
        
        // 查找需要插入的位置
        while(p >= 0 && arr[p] > cur) {
            // arr[p] 大于cur时,需要将元素往后移动
            arr[p + 1] = arr[p];
            p--;
        }
        
        // 停止循环的位置为元素插入的前一位
        arr[p + 1] = cur;
    }
}

三、快速排序

思路:

  1. 在待排序的元素任去一个元素作为基准
  2. 将待排序的元素进行分区,比基准元素大的元素放在他的右边,比起小的元素放在左边
  3. 将左右两个分区重复上面的步骤知道所有的元素都是有序的
function quickSort(arr) {
    const len = arr.length;
    if(arr.length === 1 || !arr.length) {
        return arr;
    }
    const middle = Math.floor(len / 2);
    const cur = arr.splice(middle, 1)[0];
    const left = [];
    const right = [];
    for(let i = 0; i < len - 1; i++) {
        let item = arr[i];
        item <= cur ? left.push(item) : right.push(item);
    }

    return quickSort(left).concat(cur, quickSort(right));
}

四、选择排序

思路:
每次循环找到本次的最小值,放到被本次循环的开始的位置。

function minSort(arr) {
    // 循环到倒数第二位的时候,就能排好所有的顺序了
    for(let i = 0, end = arr.length -1; i < end; i++) {
        let minI = i;
        for(let j = i + 1; j <= end; j++) {
            if(arr[minI] > arr[j]) {
                minI = j;
            }
        }
        if(minI !== i) {
            [arr[i], arr[minI]] = [arr[minI], arr[i]];
        }
    }
    return arr;
}

五、希尔排序

function shellSort(arr) {
    let len = arr.length,
        temp,
        gap = 1;
    while (gap < len / 3) { //动态定义间隔序列
        gap = gap * 3 + 1;
    }
    for (gap; gap > 0; gap = Math.floor(gap / 3)) {
        for (var i = gap; i < len; i++) {
            temp = arr[i];
            let j = i - gap;
            while(j >= 0 && arr[j] > temp) {
                arr[j + gap] = arr[j];
                j -= gap;
            }
            arr[j + gap] = temp;

        }
    }
    return arr;
}