插入排序的思想: 默认有一个无序表和一个有序表,有序表中存储着数组的第一个元素,其实可以用一个数组来表示。首先取得一个元素,将其和它前面的元素进行比较,也就是说有一个待插入元素,一个待检查元素,它们之间进行比较,如果待插入元素比待检查元素小,那么待检查元素后移,待检查元素索引前移,取得前一个元素继续进行比较,直到待插入元素比待检查元素大,那么表示合适的位置找到,由于每个比待插入元素大的元素都后移过,因此实际上insertIndex(待检查元素索引)的后一位是可以插入的,可以理解为一个空位,因此就可以将其插入。如果到达数组最前面,也就是索引为-1了还是没找到,那么跳出当前循环,进行插入。 注意:实际上待插入元素不会因为待检查元素后移导致被抹去,因为存储在insertVal中 优化: 如果待检查元素索引insertIndex的下一位就是i(待插入元素的索引),那么就可以不进行插入,因为待插入元素就是最大的数了
完整代码(使用了Kotlin扩展方法完成,对IntArray进行扩展)
package com.sort
import java.text.SimpleDateFormat
import java.util.Date
fun main() {
// val array = intArrayOf(101,35,119,1)
val array = IntArray(80000)
for (i in 0 until 80000) {
array[i] = (Math.random() * 8000000).toInt()
}
val date = Date()
val simpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
val format1 = simpleDateFormat.format(date)
println("插入前的时间:$format1")
array.insertSort()
val date2 = Date()
val format2 = simpleDateFormat.format(date2)
println("插入前的时间:$format2")
// println(array.contentToString())
}
// 插入排序
fun IntArray.insertSort() {
for (i in 1 until this.size) {
val insertVal = this[i]
// 当前元素的前一个位置
var insertIndex = i - 1
// 然后依次将该元素和之前的元素进行比较
// insertIndex表示检查插入是否合法的位置
// 1.insertIndex >= 0 表示检查的位置不能小于0
// 2.insertVal < array[insertIndex] 表示待插入的元素小于检查的位置
// 如果小于就不插入,因为说不定前面还有更小的数,只有比检查的位置的数大的时候才进行插入
// 这样就说明比当前检查的数大,比前一个检查的数小,是合适的位置
while (insertIndex >= 0 && insertVal < this[insertIndex]) {
// 将检查的数后移
// 本身insertIndex就是i-1,所以再次减1表示是当前拿到的需要排序的数的前前个位置
this[insertIndex + 1] = this[insertIndex]
insertIndex--
}
// 说明找到了位置,之所以+1是因为当前insertIndex是检查的数的索引,也就是说这个检查的数是比待插入的数大。
// 或者因为找到了-1的索引,不符合条件,到达了最前面
// 优化:如果当前找到的位置的后一位就是当前这个数,那么不需要插入,因为就是它本身
if (insertIndex + 1 != i) {
this[insertIndex + 1] = insertVal
}
}
}