1、概述

插入排序是简单直观且稳定的排序算法。

插入排序的基本操作是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数+1的有序数据,适用于少量数据的排序。

插入排序主要是将排序数组分成两部分,第一部分是包含这个数组的左右元素,但最后一个元素除外(数组有多余的空间才可插入),第二部分是需要插入的元素,在第一部分排序完成后,再将这个待插入放入元素插入到已排好序的第一部分中。

插入的过程其实是不断交换和比较的过程。

2、算法原理

基本思想:每步将一个待排序的记录,岸其关键码值的大小插入前面已经排好序的数列的适当位置中,知道全部插入为止

步骤:

1)从第一个元素开始,该元素可以认为已经被排序

2)取出下一个元素,在已经排序的元素序列中从后往前扫描

3)如果该元素(已排序)大于新元素,将该元素移到下一个位置

4)重复3,直到找到已排序的元素小于或等于新元素的位置

5)将新元素插入到该位置

6)重复2)~5)

3、举例

整理一个无序数组 [8, 3, 5, 4, 6]

1)取出第一个数字8,得到数组[8],无序数组为[3, 5, 4, 6]

2)取出第二个数字3,插入新数组,3<8,得到[3, 8],无序数组为[5, 4, 6]

3)取出第三个数字5,插入新数组,5<8且5>3,得到[3, 5 ,8],无序数组为[4, 6]

4)取出第四个数字4,插入新数组,4<8、4<5、4>3,得到[3, 4, 5, 8],无序数组为[6]

5)最后取出数字6,插入新数组,6>5、6<8,得到[3, 4, 5, 6, 8],排序完成

swift算法之排序:(三)插入排序_数组

4、算法实现

1)新建数组,符合条件的插入来实现插入排序

func insertSort(_ array : [Int])->[Int]{
        var list = array
        //建立一个空数组,符合条件的插入,没插入的尾后添加
        var newList = [list[0]]
        //记录循环的次数
        var count = 0
        for i in 1..<list.count {
//            var max : Int? = nil //从大到小排序
            var min : Int? = nil//从小到大排序
            count = i
            for j in 0..<newList.count {
//                if list[i] > newList[j] {
//                    max = i
                if list[i] < newList[j] {
                    min = i
                    newList.insert(list[i], at: j)
                    break
                }
                
            }
//            if max == nil {
//                newList.append(list[i])
//            }
            if min == nil {
                newList.append(list[i])
            }
        }
        print(newList)
        print("count: ",count)
         return newList
    }

2)通过交换数组数据实现插入排序

func insertSort1(_ array : [Int])->[Int]{
        var list = array
        //记录循环次数
        var count = 0
        for i in 1..<list.count {
            //从i往前找,符合条件交换
            var y = i
            count = i
            //从大到小排序
//            while y>0 && list[y]>list[y-1]{
//                list.swapAt(y, y-1)
//                y -= 1
//            }
            //从小到大排序
            while y>0 && list[y]<list[y-1]{
                list.swapAt(y, y-1)
                y -= 1
            }
        }
        print(list)
        print("count: ",count)
        return list
    }

3)通过移动数组数据实现插入排序

func insertSort2(_ array : [Int])->[Int]{
        var list = array
        var count = 0
        for i in 1..<list.count {
            count = i
            //从i往前找,符合条件移动
            var y = i
            let tmp = list[y]
            //从大到小排序
//            while y>0 && tmp>list[y-1]{
//                list[y] = list[y-1]
//                y -= 1
//            }
            //从小到大排序
            while y>0 && tmp<list[y-1]{
                list[y] = list[y-1]
                y -= 1
            }
            list[y] = tmp
        }
        print(list)
        print("count: ",count)
        return list
    }

4)插入排序实现通用化

func insertSort3<T>(_ array : [T], _ isOrderedBefore:(T, T)->Bool)->[T]{
        var list = array
        var count = 0
        for i in 1..<list.count {
            count = i
            //从i往前找,符合条件移动
            var y = i
            let tmp = list[y]
            //从大到小排序
            //            while y>0 && tmp>list[y-1]{
            //                list[y] = list[y-1]
            //                y -= 1
            //            }
            //从小到大排序
            while y>0 && isOrderedBefore(tmp, list[y-1]){
                list[y] = list[y-1]
                y -= 1
            }
            list[y] = tmp
        }
        print(list)
        print("count: ",count)
        return list
    }

5)调用

        let array3 = [8, 3, 5, 4, 6]
        SortSummary.insertSort(array3)
        SortSummary.insertSort1(array3)
        SortSummary.insertSort2(array3)
        SortSummary.insertSort3(array3, <)
        //insertSort3(array3){$0<$1}等同于insertSort3(array3, <)
        SortSummary.insertSort3(array3){$0<$1}
        SortSummary.insertSort3(array3, >)


运行结果:
1)新建数组
[3, 4, 5, 6, 8]
count:  4

2)交换
[3, 4, 5, 6, 8]
count:  4

3)移动
[3, 4, 5, 6, 8]
count:  4

4)通用方法
//从小到大排列
[3, 4, 5, 6, 8]
count:  4
[3, 4, 5, 6, 8]
count:  4
//从大到小排列
[8, 6, 5, 4, 3]
count:  4

5、时间复杂度

1)最好的情况下,完全没有任何数据移动,即O(n)

2)最坏的情况下(平均性能表现),比较的次数为(n+2)*(n+1)/2,移动的次数最大值(n+4)*(n-1)/2, 即O(n^2)

3)平均时间复杂度为 O(n^2)

 

github代码

注:排序的具体实现代码在 SortSummary.swift 文件里 调用是在 ViewController.swift