排序算法简述(4种)

231 阅读2分钟

选择排序

选择排序的原理:每次挑出最小的那个数字,放在第一位,然后在比较剩余的数字

//伪代码(使用递归)
let sort = (numbers) => {
    if(numbers.length > 2){
    numbers.splice(minIndex,1)
    return minNumbers + sort(numbers)
    }else{
        return sort2(numbers)
    }
}
// 辅助函数
let sort2 = (numbers) => {
    return numbers[0] > numbers[1] ? numbers.reverse() : numbers
}

let min = (numbers) => 
    numbers.length > 2 ? min(
    [numbers[0],min(numbers.slice(1))]
    ) : Math.min.apply(null,numbers)
    
let index = (numbers) => numbers.indexOf(min(numbers))

//代码
let sort = (numbers) => {
    if(numbers.length > 2){
            console.log('----')
    let minIndex = index(numbers)
    let minNumbers = min(numbers) 
            console.log(`minIndex : ${minIndex}`)
            console.log(`minNumbers : ${minNumbers}`)
    numbers.splice(minIndex,1)
    return [minNumbers].concat(sort(numbers))
    }else{
        return sort2(numbers)
    }
}
//(不使用递归)
let sort = (numbers) => {
    for(let i = 0; i < numbers.length - 1; i++){
        let minIndex = index(numbers.slice(i)) + i
        if (minIndex !== i){
            swap(numbers,minIndex,i)
        }
    }
    return numbers
}
//辅助代码、
let min = (numbers) => 
    numbers.length > 2 ? min(
    [numbers[0],min(numbers.slice(1))]
    ) : Math.min.apply(null,numbers)
    
let index = (numbers) => numbers.indexOf(min(numbers))

let swap = (numbers,a,b)=>{
    let temp = numbers[a]
    numbers[a] = numbers[b]
    numbers[b] = temp
}

let swap = (numbers,a,b) => {
    [numbers[a],numbers[b]] = [numbers[b],numbers[a]]
}

快速排序

原理:选择一个基准,比基准小的,排在左边,比基准大的排在右边,重复length-1次 快速排序需要使用splice取pivot,因为splice会改变原数组,删去pivot,否则会重复获取pivot,导致爆栈。

//伪代码
let quickSort = numbers =>
    numbers[i] < pivot ? numbers[i] + left : numbers[i] + right
    quicksort(left) + pivot + quickSort(right)
//辅助函数
let pivotIndex = numbers => 
    Math.floor(numbers.length/2)

let pivot = numbers => 
    numbers.splice(pivotIndex(numbers),1)[0]

//代码
let quickSort = numbers =>{
    if (numbers.length <= 1){return numbers}
    let left = []
    let right = []
    let pivotNumbers = pivot(numbers)
    for (let i = 0; i < numbers.length; i++){
        if (numbers[i] < pivotNumbers){
            left.push(numbers[i])
        }else{
            right.push(numbers[i])
        }
        
        
        console.log(`----`)
        console.log(`left: ${left}`)
        console.log(`right: ${right}`)
        console.log(`pivotNumbers : ${pivotNumbers}`)
        console.log(`numbers : ${numbers}`)
    }
    
    return quickSort(left).concat([pivotNumbers],quickSort(right))
}

归并排序

原理:将数组完全拆分,在比较各个数组的大小

//伪代码
let mergeSort = (numbers) => {
    merge(mergeSort(left),mergeSort(right))
}

let merge = (a,b) => {
    if (a.length === 0){return b}
    if (b.length === 0){return a}
    if (a[0] > b[0]){return [b[0]].concat(merge(a,b.slice[1]))
    }
    if (a[0] < b[0]){
        return [a[0]].concat(merge(a.slice(1),b))
    }
}
//代码
let mergeSort = (numbers) => {
    let k = numbers.length
    if (k === 1){return numbers}
    let left = numbers.slice(0,Math.floor(k/2))
    let right = numbers.slice(Math.floor(k/2))
    return merge(mergeSort(left),mergeSort(right))
}

let merge = (a,b) => {
    if (a.length === 0){return b}
    if (b.length === 0){return a}
    if (a[0] > b[0]){return [b[0]].concat(merge(a,b.slice(1)))
    }else{
        return [a[0]].concat(merge(a.slice(1),b))
    }
}

计数排序

原理: 利用哈希表,遍历数组,使其变为哈希表,在遍历哈希表,从小到大排序

//伪代码
let countSort = (numbers) => {
    if (! i in hashTable){
        hashTable[numbers[i]] = 1
    }else{
        hashTable[numbers[i]] += 1
    }
    let max = max.numbers[i]


for (let i = 0; i <= max; i++){
    if (i in hashTable){
        result.push(i) + countNumber i
    }
}
return result
}
let countSort = numbers => {
    let result = []
    let hashTable = {}
    let max = 0
    for (let i = 0; i < numbers.length; i++){
        if (! (numbers[i] in hashTable)){
        hashTable[numbers[i]] = 1
    }else{
        hashTable[numbers[i]] += 1
    }
    console.log(`----`)
    console.log(`hashTable : ${Object.entries(hashTable)}`)
    if(numbers[i] > max) {max = numbers[i]}
    console.log(`max : ${max}`)
    }
    
    for(let j = 0; j <= max; j++){
    // 因为j=0 所以 无法排序负数
        if(j in hashTable){
            for(let k = 0 ; k < hashTable[j]; k++){
                result.push(j)
                console.log(`j:${j}`)
            }
        }
    }
    return result
}

时间复杂度

  1. 选择排序 : O(n**2)
  2. 快速排序 : O(n log2 n)
  3. 归并排序 : O(n log2 n)
  4. 计数排序 : O(n + max)