JS排序,看这一篇就够了!

133 阅读1分钟

交换排序

冒泡排序

        //冒泡排序
        let bubbleSort = (arr) => {
            for (let i = 0; i < arr.length - 1; i++) {
                for (let j = 1; j < arr.length - i; j++) {
                    if (arr[j] < arr[j - 1]) [arr[j - 1], arr[j]] = [arr[j], arr[j - 1]];
                }
            }
            return arr
        }

快排

        //快速排序*****递归*****新建地址空间
        let quickSort = (arr) => {
            if (arr.length < 2) return arr;
            let left = [], right = [];

            for (let i = 1; i < arr.length; i++) {
                if (arr[i] < arr[0]) {
                    left.push(arr[i])
                } else {
                    right.push(arr[i])
                }
            }
            return [...quickSort(left), arr[0], ...quickSort(right)]
        }
        //快速排序*****递归*****原地递归
        let quickSort = (arr) => {
            let help = (arr, left, right) => {
                if (left >= right) return arr;
                let i = left, j = right, flag = left;
                while (i < j) {
                    while (arr[j] > arr[flag] && j > flag) j--;
                    if (i >= j) break;
                    while (arr[i] <= arr[flag] && i < j) i++;
                    [arr[flag], arr[j], arr[i]] = [arr[j], arr[i], arr[flag]];
                    flag = i;
                }
                help(arr, left, flag - 1);
                help(arr, flag + 1, right);
                return arr
            }
            return help(arr, 0, arr.length - 1)
        }
        //快排***非递归*****以后快排都要写成自身排序的形式*****性能最优
        let quickSort = (arr) => {
            let stack = [[0, arr.length - 1]]
            while (stack.length > 0) {
                let temp = stack.pop();
                if (temp[0] >= temp[1]) continue;
                let i = temp[0], j = temp[1], flag = i;
                while (i < j) {
                    while (arr[j] > arr[flag] && j > flag) j--;
                    if (i >= j) break;
                    while (arr[i] <= arr[flag] && i < j) i++;
                    // let temp1 = arr[flag];
                    // arr[flag] = arr[j];
                    // arr[j] = arr[i];
                    // arr[i] = temp1;

                    //先交换的两个元素先写
                    [arr[flag], arr[j], arr[i]] = [arr[j], arr[i], arr[flag]];

                    // [arr[flag], arr[j]] = [arr[j], arr[flag]];
                    // [arr[i], arr[j]] = [arr[j], arr[i]];

                    flag = i;
                }
                stack.push([temp[0], flag - 1]);
                stack.push([flag + 1, temp[1]])
            }
            return arr;
        }

插入排序

直接插入排序

        //直接插入排序
        let insertSort = (arr) => {
            for (let i = 1; i < arr.length; i++) {
                let temp = arr[i];
                let index = i;
                for (let j = i - 1; j >= 0 && temp < arr[j]; j--) {
                    arr[j + 1] = arr[j]
                    i--;
                }
                arr[i] = temp;

            }
            return arr;
        }

希尔排序

        //希尔排序*****时间复杂度优于O(n^2)
        let shellSort = (arr) => {
            for (let gap = Math.floor(arr.length / 2); gap > 0; gap = Math.floor(gap / 2)) {
                for (let i = gap; i < arr.length; i++) {
                    let j = i;
                    let temp = arr[i];
                    while (j - gap >= 0 && temp < arr[j - gap]) {
                        arr[j] = arr[j - gap];
                        j -= gap;
                    }
                    arr[j] = temp;
                }
            }
            return arr;
        }

选择排序

简单选择排序

        //简单选择排序
        let selectSort = (arr) => {
            for (let i = 0; i < arr.length - 1; i++) {
                for (let j = i + 1; j < arr.length; j++) {
                    if (arr[j] <= arr[i]) [arr[j], arr[i]] = [arr[i], arr[j]];
                }
            }
            return arr;
        }

堆排序

        //堆排序
        const heapSort = (arr, k) => {
            let res = [];
            
            //构建堆
            let heap = (arr, i) => {
                let l = i * 2 + 1, r = i * 2 + 2, smallest = i;
                if (l < arr.length && arr[l] < arr[smallest]) smallest = l;
                if (r < arr.length && arr[r] < arr[smallest]) smallest = r;
                if (smallest !== i) {
                    [arr[i], arr[smallest]] = [arr[smallest], arr[i]];
                    heap(arr, smallest);
                }
            }

            //遍历数组构建堆,注意:第一个非叶子节点序号为Math.floor(arr.length / 2) - 1
            for (let i = Math.floor(arr.length / 2) - 1; i >= 0; i--) {
                heap(arr, i)
            }

            //将第一个和最后一个元素交换位置,在从新构建堆
            for (let i = arr.length - 1; i >= 0; i--) {
                [arr[0], arr[i]] = [arr[i], arr[0]];
                res.push(arr[i]);
                arr.splice(i, 1);
                heap(arr, 0);
            }
            return res
        }

归并排序

二路归并排序

        // 归并排序
        let mergeSort = (arr) => {
            let merge = (left, right) => {
                let res = [];
                let l = r = 0;

                while (l < left.length && r < right.length) {
                    if (left[l] < right[r]) {
                        res.push(left[l]);
                        l++;
                    } else {
                        res.push(right[r]);
                        r++;
                    }
                }
                while (l < left.length) {
                    res.push(left[l]);
                    l++;
                }
                while (r < right.length) {
                    res.push(right[r]);
                    r++;
                }
                return res;
            }


            if (arr.length === 1) {
                return arr;
            }
            let mid = Math.floor(arr.length / 2);
            let left = arr.slice(0, mid);
            let right = arr.slice(mid)

            //合并数组
            return merge(mergeSort(left), mergeSort(right))

        }

时间复杂度和空间复杂度这些老生常谈的东东,先码住。以后有时间再加。


记录记录!