排序算法

55 阅读1分钟

冒泡排序

        const bubbleSort = (arr) => {

            if (arr.length <= 1) return arr;

            for (let i = 0; i <= arr.length - 1; i++) {
                let flag = true;

                for (let j = 0; j <= arr.length - 1 - i; j++) {
                    if (arr[j] > arr[j + 1]) {
                        flag = false;
                        [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]
                    }
                }

                if (flag) {
                    break;
                }
            }
            return arr;
        }

选择排序

    const selectSort = (arr) => {
            let len = arr.length;
            if (len <= 1) return arr;

            for (let i = 0; i < len; i++) {
                let min = i;
                for (let j = min + 1; j < len; j++) {
                    if (arr[min] > arr[j]) {
                        min = j;
                    }
                }
                [arr[min], arr[i]] = [arr[i], arr[min]]
            }
            return arr;
        }

插入排序

     const insetSort = (arr) => {
            let len = arr.length;
            if (len <= 1) return arr;

            for (let i = 1; i < len; i++) {

                let tmp = arr[i]

                let j = i;

                while (arr[j - 1] > tmp && j > 0) {
                    arr[j] = arr[j - 1]
                    j--
                }

                arr[j] = tmp
            }

            return arr;
        }

希尔排序

    const shellSort = (arr) => {
            let len = arr.length;

            if (len <= 1) return arr;

            let gap = Math.floor(len / 2);

            while (gap >= 1) {

                for (let i = gap; i < len; i++) {

                    let tmp = arr[i];
                    let j = i;

                    while (arr[j - gap] > tmp && j > gap - 1) {
                        arr[j] = arr[j - gap]
                        j -= grap;
                    }

                    arr[j] = tmp;
                }

                gap = Math.floor(gap / 2)

            }

            return arr;
        }

归并排序

    const merge = (leftArr, rightArr) => {
            const result = []

            while (leftArr.length && rightArr.length) {

                leftArr[0] > rightArr[0] ? result.push(rightArr.shift()) : result.push(leftArr.shift())
            }

            while (leftArr.length) {
                result.push(leftArr.shift())
            }

            while (rightArr.length) {
                result.push(rightArr.shift())
            }

            return result;
        }


        const mergeSort = (arr) => {
            if (arr.length <= 1) return arr;

            const minIndex = Math.floor(arr.length / 2) | 0;

            let leftArr = arr.slice(0, minIndex);

            let rightArr = arr.slice(minIndex, arr.length)

            return merge(mergeSort(leftArr), mergeSort(rightArr))

        }

快速排序

    //方式一:
    const quickSort = (arr) => {
            if (arr.length <= 1) return arr;

            const pivot = Math.floor(arr.length / 2) | 0;

            const curItem = arr.splice(pivot, 1)[0];

            let leftArr = [], rightArr = [];

            arr.forEach(item => {
                item <= curItem ? leftArr.push(item) : rightArr.push(item)
            });

            return quickSort(leftArr).concat(curItem).concat(quickSort(rightArr))

        }
    
    
    //方式二:
    const quickSort2 = (arr, left, right) => {          //这个left和right代表分区后“新数组”的区间下标,因为这里没有新开数组,所以需要left/right来确认新数组的位置
            if (left < right) {
                let pos = left - 1                      //pos即“被置换的位置”,第一趟为-1
                for (let i = left; i <= right; i++) {    //循环遍历数组,置换元素
                    let pivot = arr[right]              //选取数组最后一位作为基准数,
                    if (arr[i] <= pivot) {               //若小于等于基准数,pos++,并置换元素, 这里使用小于等于而不是小于, 其实是为了避免因为重复数据而进入死循环
                        pos++
                        let temp = arr[pos]
                        arr[pos] = arr[i]
                        arr[i] = temp
                    }
                }
                //一趟排序完成后,pos位置即基准数的位置,以pos的位置分割数组
                quickSort2(arr, left, pos - 1)
                quickSort2(arr, pos + 1, right)
            }
            return arr      //数组只包含1或0个元素时(即left>=right),递归终止
        }
    

image.png