十大排序详解

 冒泡排序(n2)

第一层循环遍历外层 length -1个项,对前length-1 个数排序

内层循环遍历到length - i -1,对前length - i -1个数冒泡

function bubbleSort(arr) {
    for (let i = 0; i < arr.length - 1; i++) {
        for (let j = 0; j < arr.length - i - 1; j++) {
            const temp = arr[j + 1]
            arr[j + 1] = arr[j]
            arr[j] = temp
        }
    }
}

选择排序(n2)

从乱序区中选择最小加入顺序区

外层循环:扩展乱序区域到length-1

内层循环:选择乱序区域中最小下标

function selectSort(arr) {
    for (let i = 0; i < arr.length - 1; i++) {
        let minIndex = i
        for (let j = i + 1; j < arr.length; j++) {
            if (arr[j] < arr[minIndex]) {
                minIndex = j
            }
        }
        const tmp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = tmp;
    }
}

插入排序(n2)

从乱序区中随便选一个,找到其在乱序区域中的位置

外层循环 :扩展有序区域,到length-1

内层循环:在有序区中找到插入的位置

用pre和current辅助寻找位置

function insertionSort(arr) {
    for (let i = i; i < arr.length - 1; i++) {
        let preIndex = i - 1
        let current = arr[i]
        while (preIndex > 0 && arr[preIndex] > current) {
            arr[preIndex + 1] = arr[preIndex]
            preIndex--
        }
    }
    arr[preIndex + 1] = current
}

希尔排序(nlogn~nlog2n)

用gap将数组拆分,每一小数组再进行插入排序

外外层循环:gap每次折一半,直至gap为0

function shellSort(arr) {
    for (let gap = Math.floor(arr.length); gap > 0; gap = Math.floor(arr / 2)) {
        for (let i = gap; gap < arr.length; i++) {
            const curr = arr[i]
            let j = i
            while (j - gap > 0 && arr[j-gap] >curr) {
                arr[j]=arr[j-gap]
                j=j-gap
            }
            arr[j]=curr
        }
    }
}

归并排序(nlogn)

标准分治法,划分为两个数组,递归解决。


function mergeSort(arr) {
    function sort(arr, left, right) {
        if (left < right) {
            const mid = (left + right) / 2
            leftArr = sort(arr, left, mid)
            rightArr = sort(arr, mid + 1, right)
            return merge(leftArr, rightArr)
        }
        return left > 0 ? [arr[left]] : []
    }
    function merge(leftArr, leftArr) {
        const res = []
        const leftPtr = 0
        const rightPtr = 0
        while (leftPtr < leftArr.length && rightPtr < rightArr.length) {
            if (leftArr[leftPtr] < leftArr[rightPtr]) {
                res.push(leftArr[leftPtr++])
            } else {
                res.push(rightArr[rightPtr++])
            }
        }
        while (leftPtr < leftArr.length) {
            res.push(leftArr[leftPtr++])
        }
        while (rightPtr < rightArr.length) {
            res.push(rightArr[rightPtr++])
        }
        return res
    }
}

快速排序(nlogn-n2)

分治法,选取首个元素,将数组分为大于元素的一组和小于元素的一组。递归解决

主要包括四个步骤

后往前,找比x小

交换

前往后,找比x大

交换

function quickSort(arr) {
    function sort(arr, low, high) {
        let i = low
        let j = high
        const x = arr[low]
        while (i < j) {
            while (i < j && arr[j] > x) {
                j--
            }
            if (i < j) {
                arr[i] = arr[j]
                i++
            }
            while (i < j && arr[i] < x) {
                i++
            }
            if (i < j) {
                arr[j] = arr[i]
                j--
            }
        }
        arr[i] = x
        sort(arr, low, i - 1)
        sort(arr, i + 1, high)
    }

}

计数排序(n+k)

确定数组范围,开辟连续的空间,一次存储,按照空间顺序读取

类似哈希表,将下标作为数值存入

// 计数排序
function countingSort(arr) {
    let maxValue = Number.MIN_VALUE
    let minValue = Number.MAX_VALUE
    const res = []
    // 确定空间
    arr.forEach(num => {
        maxValue = num > maxValue ? num : maxValue
        minValue = num > minValue ? minValue : num
    })
    if (minValue < 0) {
        offset = -minValue
    }
    const bucket=new Array(maxValue+offset+1).fill(0)
    // 存入对应下标
    arr.forEach(num=>{
        bucket[num+offset]++
    })
    bucket.forEach((store,index)=>{
        while(store--){
            res.push(index-offset)
        }
    })
    return result
}

基数排序

对每一位放入不同的桶中

堆排序

 大顶堆:根节点比孩子都大

1、前置函数,维护大顶堆的性质

交换根节点与最大值

递归维护被交换结点的性质

 2、构建大顶堆(从第一个父节点n/2-1)

从第一个叶子节点的父节点开始:n - 2 / 2 = n / 2 - 1

遍历每一个节点,进行性质维护

3、排序( 从最后一个元素开始)

将头部与尾部交换

然后断开尾部连接

维护大顶堆

此时尾部为最大

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值