目标:从小到大(或从大到小)对数组进行排序
插入排序算法的步骤
- 1.通过外部传来的数组,创建一个临时数组,用来排序
- 2.外循环来拿每一个元素(目标值),索引从1开始
- 3.通过外循环的i创建临时索引j,
j=i
,内循环需要索引j - 4.内循环while里,比较目标值与目标值的前一个值
- 如果目标值 < 前一个值,对应索引设置成前一个值,临时索引j-1,继续内循环
- 如果目标值 > 前一个值,对应索引设置成目标值
示例:
let numbersArray = [1, 4, 6, 2, 8]
let sortArray = insertionSort(elements: numbersArray)
插入排序
// 这个函数里有两个循环
func insertionSort(elements: [Int]) -> [Int] {
// 不能直接修改参数elements
// 所以使用array这个临时变量来进行排序
var array = elements
// 外部循环遍历数组中的每个元素,注意:索引从1开始
for i in 1..<array.count {
// 比较的目标值
let compareValue = array[i]
// 临时索引,内循环需要用
var j = i
// 取出需要比较的值2,这个值跟前边一个比较,如果比前边的小
// 那么先让当前对应的索引的值,修改为前边的值(比如2与6比较,array[3]=6)
// 临时变量j同时-1,继续拿着2跟前边的4进行比较
// 2<4,所以修改当前对应的索引所对应的值为4(array[2]=4)
// 临时变量j同时-1,
// 2>1,找到了对应的位置索引,排序array[1] = 2
// 内循环:对应外循环的目标值compareValue,与之前的元素进行比较
while compareValue < array[j-1] && j > 0{
array[j] = array[j-1]
j -= 1
}
// [1, 4, 6, 2, 8]
// 如果目标值(比如4)compareValue > array[j-1](比如1)
// 那么array[1] = compareValue,直接排序,然后进入下一个外循环,去比较6
array[j] = compareValue
}
return array
}
插入排序的核心:内循环里面是已经排好序的,外循环的目标值插入到内循环的对应位置
外循环的目标值与内循环里面相邻值挨个比较,如果目标值比前一个值大,直接排序,array[j] = compareValue
;
如果目标值比前一个值小,那么当前索引所对应的值=前面的值,array[j] = array[j-1]
,继续对目标值与前面的值比较,重复操作,直到索引为0,停止内循环
性能
最坏情况下插入排序的平均情况性能是 O(n ^ 2) 。 这是因为在这个函数中有两个嵌套循环。 其他排序算法(如快速排序和合并排序)的性能是 O(n log n),在数据量较大时更快
插入排序实际上对排序小数组非常快。 当元素个数为10或更小需要排序的时候,一些标准库会把它们的排序方法从快速排序切换到插入排序。