排序算法之插入排序

1. 直接插入排序

概念:直接插入排序是一種最簡單的排序方法,它的基本操做是將一個記錄插入到已排好序的有序表中,從而獲得一個新的、表長度增1的有序表。
思路:簡單來講就是假設表中第一項已經排好序,而後拿第二項去和第一項比較大小,若第一項大,則交換位置,反之進行下一輪比較,前兩項已經排好序,則第三項與第二項比較,若比第二項小,交換位置,再和第一項比較大小,若此時的第二項(通過上一次的交換)比第一項小,再次交換位置,如此類推。
代碼實現數組

function insertSort(arr) {
    if (arr.length < 2) return
    // 假設第一個數字已經排好 故此處i從1開始
    for (let i = 1; i < arr.length; i++) {
       // j爲當前i的前一個,若後一項比前一項值大,則交換位置
       // 每一次內層for循環開始,設置下標爲i的數據項爲崗哨,即arr[i] = arr[j=1],而後和前j項做比較
       // 內層for每所有執行一遍,更新一次數組排序,稱爲一趟j排序
        for (let j = i - 1; j > -1; j--) {
            let temp = 0
            if (arr[j] > arr[j+1]) {
                temp = arr[j]
                arr[j] = arr[j+1]
                arr[j+1] = temp
            }else {
                break
            }
        }
        console.log(arr)
    }
}
insertSort([6, 5, 3, 1, 8, 7])

執行結果
直接插入排序截圖.png
時間複雜度spa

  • 若須要排序的數組原本就是定期望的順序或者逆序排好的,則時間複雜度爲數組長度,即O(n)
  • 若初始數組是定期望排序的逆序排列的,則時間複雜度爲O(n²)

2. 折半插入排序

概念:折半插入排序是在直接插入排序的基礎之上,增長了一箇中間元素位置,減小了元素比較次數,移動次數未變。
實現思路:一樣設置哨兵元素arr[i],在已存在的有序序列前1至i-1個元素中找到中間位置mid,mid=(low+high)/2,而後拿哨兵元素與arr[mid]進行比較,若小於哨兵元素,則在Mid以前找插入位置,若大於哨兵元素,則在Mid以後找插入位置。
代碼實現code

function BinserSort(arr) {
    if (arr.length < 2) return arr
    let low = 0, high = 0, j =0, temp =0
    for (let i = 1; i < arr.length; i++) {
        if (arr[i] < arr[i - 1]) {
            temp = arr[i]
            low = 0
            high = i - 1
            let mid =0
            while(low <= high) {
                // mid 設置已排序列的中間位置
                mid = Math.floor((low + high) / 2)
                // 若崗哨元素比中間位置元素大,則低位下標在中間位置以後後移
                if (temp > arr[mid]) {
                    low = mid + 1
                } else {
                    // 若崗哨元素比中間位置元素小,則高位下標在中間位置以前前移
                    high = mid - 1
                }
            }
            // 比較崗哨元素與前low個元素,同直接排序
            for (j =i; j > low; j--) {
                arr[j] = arr[j - 1]
            }![折半插入排序.png](/img/bVbF1SZ)
            arr[j] = temp
            console.log('mid', mid, 'arr', arr)
        }
    }
}
console.log('arr=',[9, 2, 75, 23, 44])
BinserSort([9, 2, 75, 23, 44])

執行結果
折半插入排序.png
時間複雜度blog

  1. 若已是有序序列,則爲O(n)
  2. 如果逆序序列爲O(n²)
  3. 因此平均時間複雜度爲O(n²)
相關文章
相關標籤/搜索