JavaScript基础算法第一天

108 阅读2分钟

「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战

排序算法

分治:分而治之,先解决子问题,再将子问题的解合并求出原问题

插入排序

  • 稳定
  • 空间复杂度O(1)
  • 时间复杂度O(n^2)

原理

通过比较当前元素和前面的元素,如果大于则进行交换,不断循环直到结束

数组长度10以内,插入排序又快又稳

代码

const insertionSort = function (arr) {
    const len = arr.length
    for(let i = 1; i < len; i++) {
        let curr = arr[i]
        let prev = i - 1
        while(prev >= 0 && arr[prev] > curr){
            arr[prev + 1] = arr[prev--]
        }
        arr[prev + 1] = curr
    }
    return arr
}

快速排序

阮一峰

原理

  1. 通过随机获取中间值

  2. 在进行循环判断放入左侧的子集还是右侧的子集

  3. 不断重复,第一步和第二步,直到所有子集只剩最后一个

代码

const quickSort = function(arr) {
    if(arr.length < 2) return arr
    // 递归的中止条件,也是判断边界值的条件
    let index = Math.floor(arr.length >> 1) 
    // 获取中位数下标
    let pivot = arr.splice(index,1)[0] 
    // 将原数组修改,提取出随机的中位数
    let left = []
    let right = []
    arr.forEach(e => pivot < e ? right.push(e):left.push(e) 
    // 判断是将e放到左侧还是右侧
    return quickSort(left).concat([pivot],quickSort(right)) 
    // 将数组重新拼接,因为是通过pivot作为中间值去判断,所以在拼接的时候左右摆放足以
}

in-place

原理

通过下标不断交换,第一次选择的下标是0

第二次则是通过第一次的选择,搜索对应的区间进行排序

阮一峰老师的则是创建空间分割数组进行排序

代码

const quickSort = function (arr) {
    // 交换元素
    const swap = function (arr,i,j) {
        let temp = arr[i]
        arr[i] = arr[j]
        arr[j] = temp
    }
    
    const partition = function (arr,left,right) {
		let pivot = arr[left]
        let storeIndex = left
        
        for(let i = left + 1; i <= right; i++) {
            if(arr[i] < pivot) {
                // 如果每次都是成功判断,数组不会发生变化,如果,中间有间隔,则是真正交换
                swap(arr,++storeIndex,i)
            }
        }
        // 将比中位数小的下标和基准数进行交换
        swap(arr,left,storeIndex)
		// 将所选择坐标向外抛出,给下一次递归使用
        return storeIndex
    }
    
    const sort = function (arr,left,right){
        if (left < right) {
           let storeIndex = partition(arr,left,right)
           sort(arr,left,storeIndex - 1)
           sort(arr,storeIndex + 1,right)
        }
    }
    
    sort(arr,0,arr.length - 1)
    
    return arr
}

稳定性

快速排序是一个不稳的的排序,因为如果两个数相等,两个数的位置会发生变化,如果是单纯的数组可能变化不大

如果是 [{class:1,name:'hmm'},{class:1,name:'li'}],通过class进行排序这两个对象将被交换

时间复杂度

最好的情况是O(nlogn),最差则是走完所有O(n²)