排序

冒泡排序

每冒泡一次有序度加1,逆序度減1數組

const bubbleSort = (arr) => {
    for(let i = 0; i < arr.length; i++){
        let isChange = false;
        for(let j = 0; j < arr.length - i - 1; j++){
            if(arr[j] > arr[j+1]){
                [arr[j],arr[j + 1]] = [arr[j + 1],arr[j]]
                isChange = true   
            }
        }
        if(!isChange)break
    }
    console.log(test)
} 

const test = [4, 5, 6, 3, 2, 1]
bubbleSort(test)

插入排序

無序數組中取一個要插入的元素和有序數組中要插入的元素進行比較,找到要插入的位置ui

const insertionSort = (arr) => {
    if(arr.length <= 1)return
    for(let i = 1; i < arr.length; i++){
        let insertVal = arr[i]
        let j = i - 1
        for(j; j >= 0; j--){
            if(insertVal < arr[j]){
                arr[j + 1] = arr[j]
            }else{
                break
            }
        }
        arr[j + 1] = insertVal
    }
    console.log(arr)
}

const testSort = [4, 1, 6, 3, 2, 1]
insertionSort(testSort)

選擇排序

每次按順序找到最小的數排在有序組裏,有序組裏的數據再也不比較指針

const selectionSort = (arr) => {
    if (arr.length <= 1) return
    for(let i = 0; i < arr.length - 1; i++){
        let minIndex = i
        for(let j = i + 1; j < arr.length; j++){
            if(arr[minIndex] > arr[j]){
                minIndex = j
            }
        }
        [arr[i],arr[minIndex]] = [arr[minIndex],arr[i]]
    }
    console.log(arr)
}
const testSelect = [4, 8, 6, 3, 2, 1, 0, 12]
selectionSort(testSelect)

歸併排序

  1. 遞推式,Left:mergerSort(0,mid),Right:mergerSort(mid)
  2. 終至條件:分裂到一個爲止
  3. 合併的時候由於已是有序的了,比較的時候找出一個相對的較大值,如這個值小的通通優先加入隊列合併,由於2個數組都是有序的,2個數組只要有一個已經所有比完說明已經排序完成,後面的就不要陪你過比了,直接合併到後面便可
const mergeSort = (arr) => {
    if(arr.length <= 1)return arr
    let mid = Math.floor(arr.length/2)
    let left = arr.slice(0,mid)
    let right = arr.slice(mid)
    
    return merge(mergeSort(left),mergeSort(right))
}

function merge(l,r){
    let res = []
    let li = 0;
    let ri = 0;
    while(li < l.length && ri < r.length){
        if(l[li] < r[ri]){
            res.push(l[li++])
        }else{
            res.push(r[ri++])
        }
    }

    while(li < l.length){
        res.push(l[li++])
    }

    while(ri < r.length){
        res.push(r[ri++])
    }

    return res
}

堆排序

  1. N - 1/2 獲取任意節點的父節點
  2. left:l * 2 + 1 獲取左子節點
  3. right: r * 2 + 2 獲取右子節點
  4. N/2 -1 獲取非葉子節點
  5. 構建大頂堆後對每次的heap的最後一個元素進行位置進行交換就能夠實現升序排序
const heapSort = (arr) => {
    if(arr.length <= 0) return arr
    let heapSize = arr.length
    heapBuild(arr,heapSize)
    while(heapSize > 1){
        heapSize -- 
        [arr[0],arr[heapSize]] = [arr[heapSize],arr[0]]
        heapIfy(arr,heapSize,0)
    }
    return arr
}

function heapBuild(arr,size){
    for(let i = Math.floor(size/2-1); i >= 0; i --){
        heapIfy(arr,size,i)
    }
}

function heapIfy(arr,size,i){
    let left = i * 2 + 1
    let right = i * 2 + 2
    let largest = i

    if(left < size && arr[left] > arr[largest]){
        largest = left
    }

    if(right < size && arr[right] > arr[largest]){
        largest = right
    }

    if(largest !== i){
        [arr[i],arr[largest]] = [arr[largest],arr[i]]
        heapIfy(arr,size,largest)
    }
}

const test = [3,5,1,6,4,7,2]
console.log(heapSort(test))

快速排序

  1. 選出主元,定義左右指針,找到大於或小於主元的元素時進行位置互換
  2. 遞歸執行1條件,直到左右指針交叉爲止
const quickSort = (arr) => {
    quick(arr,0,arr.length -1)
    console.log(arr)
}

const quick = (arr,left,right) => {
    let index
    if(arr.length > 1){
        index = partition(arr,left,right)

        if(left < index - 1){
            quick(arr,left,index - 1)
        }
        if(right > index){
            quick(arr,index,right)
        }
    }
}

function partition(arr,left,right){
    let pivot = arr[Math.floor((left + right)/2)]
    let i = left
    let j = right
    while(i <= j){
        while(arr[i] < pivot){
            i++            
        }
        while(arr[j] > pivot){
            j--
        }
        if(i <= j){
            [arr[i],arr[j]] = [arr[j],arr[i]]  
            i++
            j--
        }
    }
    return i
}

const test = [3,5,1,6,4,7,2]
quickSort(test)
相關文章
相關標籤/搜索