---页首---

排序算法-插入排序

插入排序(升序排序为例)

  • 思路:
      1. 将序列分为两个部分,头部已经排好的和后面待排序的
      1. 从头部开始遍历每一个元素,然后插入头部已排好序的恰当位置
class InsertionSort {
    var array = [5, 7, 2, 8, 9, 4, 7, 3, 2]
    
    // 使用二分搜索优化插入排序
    /**
     因为头部序列有序,可以用二分搜索快速定位到r待插入元素的最终位置
     */
    func sort() {
        for begin in 1 ..< array.count {
            // 备份要插入的函数
            let value = array[begin]
            // 用二分搜索找到插入位置
            let dest = search(index: begin)
            // 将要插入的位置到插入元素原始位置之间的d元素向后挪动1位
            for i in stride(from: begin, to: dest, by: -1) {
                array[i] = array[i - 1]
            }
            // 将元素插入准确位置
            array[dest] = value
        }
    }
    private func search(index: Int) -> Int {
        var begin = 0
        var end = index
        while begin < end {
            let mid = (begin + end) >> 1
            if array[index] < array[mid] {
                end = mid
            } else {
                begin = mid + 1
            }
        }
        return begin
    }
    
    // 优化版插入排序
    /**
        思路:将 交换 --> 挪动
     1. 先将待插入的元素备份
     2. 头部有序数据中比待插入元素大的,都朝尾部方向挪动1位
     3. 将待插入的元素放到最终的位置
     */
    func sort2() {
        for begin in 1 ..< array.count {
            var current = begin
            let value = array[current]
            while current > 0, value < array[current - 1] {
                array[current] = array[current - 1]
                current -= 1
            }
            array[current] = value
        }
    }
    // 基础版插入排序
    func sort1() {
        // 没必要从第0个元素开始,可以从第一个元素开始
        for begin in 1 ..< array.count {
            var current = begin
            while current > 0, array[current] < array[current - 1] {
                let tmp = array[current]
                array[current] = array[current - 1]
                array[current - 1] = tmp
                current -= 1
            }
        }
    }
}

最坏、平均时间复杂度: O(n^2), 最好时间复杂度:O(n)

空间复杂度: O(1)

稳定性: 稳定排序

  • 上述代码中函数 sort1 是基本插入排序的算法

插入排序的最坏和平均时间复杂度达到O(n^2)是与逆序对的数量有关,逆序对数量g越多,时间的复杂度越高
何为逆序对? 如数组: [3, 5, 8, 4, 1],y逆序对有 (3, 1) (5, 4) (5, 1) (8, 1) (4, 1),共5个逆序对
函数 sort2 做了简单优化
函数 sort 根据二分查找快速定位要插入的位置,相较 sort2 在比较次数上做了优化

posted @ 2020-04-17 17:41  20190311  阅读(123)  评论(0编辑  收藏  举报
---页脚---