排序算法之插入排序

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])

执行结果
排序算法之插入排序_第1张图片
时间复杂度

  • 若需要排序的数组本来就是按期望的顺序或者逆序排好的,则时间复杂度为数组长度,即O(n)
  • 若初始数组是按期望排序的逆序排列的,则时间复杂度为O(n²)

2. 折半插入排序

概念:折半插入排序是在直接插入排序的基础之上,增加了一个中间元素位置,减少了元素比较次数,移动次数未变。
实现思路:同样设置哨兵元素arr[i],在已存在的有序序列前1至i-1个元素中找到中间位置mid,mid=(low+high)/2,然后拿哨兵元素与arr[mid]进行比较,若小于哨兵元素,则在Mid之前找插入位置,若大于哨兵元素,则在Mid之后找插入位置。
代码实现

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])

执行结果
排序算法之插入排序_第2张图片
时间复杂度

  1. 若已经是有序序列,则为O(n)
  2. 若是逆序序列为O(n²)
  3. 所以平均时间复杂度为O(n²)

你可能感兴趣的:(javascript,算法)