冒泡排序、选择排序、插入排序与快速排序

const isSortable = v => {
    if (!Array.isArray(v) || v.length < 2) {
        throw 'Not an array or length less than 1'
    }
}
/**
 * 冒泡
 * 相邻比较,第一层表示趟数,第二层表示当前趟需要比较的次数
 * @param {*} arr 
 */
const bubleSort = arr => {
    isSortable(arr)
    const { length } = arr
    for (let i = 0; i < length; i++) {
        for (let j = 0; j < length - i - 1; j++) {
            arr[j] > arr[j + 1] && (arr.splice(j, 1, ...arr.splice(j + 1, 1, arr[j])))
        }
    }
}

/**
 * 选择排序
 * 选索引,第n趟选出第n小的索引。本趟跑完了进行比较
 * @param {*} arr 
 */
const selectionSort = arr => {
    isSortable(arr)
    const { length } = arr
    for (let i = 0; i < length; i++) {
        let cur = i
        for (let j = i + 1; j < length; j++) {
            arr[cur] > arr[j] && (cur = j)
        }
        arr[i] > arr[cur] && arr.splice(i, 1, ...arr.splice(cur, 1, arr[i]))
    }
}

/**
 * 插入排序
 * 选元素,第n趟选出区间内最小的元素,放到合适的位置, 总是保证一定区间内有序
 * 最好case, 数组有序,O(n)
 * 最坏情况, 数组倒序,O(n²)
 * @param {*} arr 
 */
const insertionSort = arr => {
    isSortable(arr)
    for (let i = 1; i < arr.length; i++) {
        // 比前一个元素小的时候才需要比较
        if (arr[i] < arr[i - 1]) {
            let cur = i
            let temp = arr[cur]
            while (cur > 0 && temp < arr[cur - 1]) {
                arr[cur] = arr[cur - 1] // 后一个元素向前移动,腾出位置
                cur--  // 继续向前比较
            }
            arr[cur] = temp
        }
    }
}

/**
 * 快排 
 * 最优: 每一次划分都将数组分为等长的两半 O(nlogn)
 * 最差, 每次划分都将数组分为0,n-1, O(n²)
 * @param {*} arr 
 */
const quickSort = arr => {
    if (arr.length <= 1) {
        return arr
    }
    const left = []
    const right = []
    const base = arr.splice(Math.floor(arr.length / 2), 1)[0]
    for (let i = 0; i < arr.length; i++) {
        arr[i] < base ? left.push(arr[i]) : right.push(arr[i])
    }
    return quickSort(left).concat(base, quickSort(right))
}

/**
 * 测试
 */
const testSort = (arr, fn) => {
    console.log(arr);
    fn(arr)
    console.log(arr)
}
const testQuickSort = (arr) => console.log(quickSort(arr))
const getMockArr = (length = 6) => Array.from({ length }).map(v => Math.floor(Math.random() * 100))
testSort(getMockArr(6), bubleSort)
testSort(getMockArr(6), selectionSort)
testSort(getMockArr(6), insertionSort)
testQuickSort(getMockArr(6))
posted @ 2022-06-28 16:51  IslandZzzz  阅读(20)  评论(0编辑  收藏  举报