直接插入排序:
算法思路:
1.数组分为两个部分:有序部分与无序部分
2.将初始数据分为有序部分和无序部分,每一步将一个无序部分的数据插入到前面已经排好序的有序部分中
3.以此类推,直到所有元素均排序完毕
平均时间复杂度:O(n2)
数据比较次数:(n - 1) + (n - 2) + (n - 3) + …… + 1 = 1/2n2 - 1/2n
数据交换次数:(n - 1)
总复杂度:1/2n2 + 1/2n - 1
最佳时间复杂度:O(n2)
最差时间复杂度:O(n)
空间复杂度:O(1)
稳定性:稳定
元素从无序部分移动到有序部分时,必须是不相等(大于或小于)时才会移动,相等时不处理
适合场景:少量元素,且基本有序
代码实现:
i : 有序序列的个数 或者 未排序序列的左侧索引
j:用来遍历数组,进行待排元素与有序序列元素的比较,并移动元素
package main
import "fmt"
func main() {
arr := []int{1, 7, 6, 7, 98, 9, -1, 7, 89, 14, -4, -5, -657}
insertSort(arr)
for _, v := range arr {
fmt.Println(v)
}
}
func insertSort(arr []int) {
for i := 1; i < len(arr); i++ {
tem := arr[i]
j := i - 1
for j = i - 1; j >= 0 && arr[j] > tem; j-- {
arr[j+1] = arr[j]
}
arr[j+1] = tem
}
}
普通插入排序:
算法思路:
1.数组分为两个部分:有序部分与无序部分
2.将初始数据分为有序部分和无序部分,每一步将一个无序部分的数据插入到前面已经排好序的有序部分中
3.以此类推,直到所有元素均排序完毕
平均时间复杂度:O(n2)
数据比较次数:(n - 1) + (n - 2) + (n - 3) + …… + 1 = 1/2n2 - 1/2n
数据交换次数:(n - 1)
总复杂度:1/2n2 + 1/2n - 1
最佳时间复杂度:O(n2)
最差时间复杂度:O(n)
空间复杂度:O(1)
稳定性:稳定
元素从无序部分移动到有序部分时,必须是不相等(大于或小于)时才会移动,相等时不处理
适合场景:少量元素,且基本有序
代码实现:
i : 有序序列的个数 或者 未排序序列的左侧索引
j:用来遍历数组,进行待排元素与有序序列元素的比较
package main
import "fmt"
func main() {
arr := []int{1, 7, 6, 7, 98, 9, -1, 7, 89, 14, -4, -5, -657}
insertSort(arr)
for _, v := range arr {
fmt.Println(v)
}
}
func insertSort(arr []int) {
for i := 1; i < len(arr); i++ {
for j := i - 1; j >= 0; j-- {
if arr[j+1] < arr[j] {
swap(arr, j+1, j)
}
}
}
}
func swap(arr []int, i, j int) {
tem := arr[i]
arr[i] = arr[j]
arr[j] = tem
}
折半插入排序
算法思路:
1.数组分为两个部分:有序部分与无序部分
2.将初始数据分为有序部分和无序部分,每一步将一个无序部分的数据插入到前面已经排好序的有序部分中
3.比较的方式为二分查找
4.以此类推,直到所有元素均排序完毕
平均时间复杂度:O(n2)
数据比较次数:(n - 1) + (n - 2) + (n - 3) + …… + 1 = 1/2n2 - 1/2n
数据交换次数:(n - 1)
总复杂度:1/2n2 + 1/2n - 1
最佳时间复杂度:O(n2)
最差时间复杂度:O(n)
空间复杂度:O(1)
稳定性:稳定
元素从无序部分移动到有序部分时,必须是不相等(大于或小于)时才会移动,相等时不处理
适合场景:少量元素,且基本有序
代码实现:
i : 有序序列的个数 或者 未排序序列的左侧索引
left, right := 二分查找的左右边界索引
tem:临时变量
j:用来遍历数组,进行后半部分的元素移动
package main
import "fmt"
func main() {
arr := []int{1, 7, 6, 7, 98, 9, -1, 7, 89, 14, -4, -5, -657}
insertSort(arr)
for _, v := range arr {
fmt.Println(v)
}
}
func insertSort(arr []int) {
for i := 1; i < len(arr); i++ {
// 二分查找
left, right := 0, i-1
tem := arr[i]
for left <= right {
mid := left + (right-left)/2
if arr[mid] > tem {
right = mid - 1
} else {
left = mid + 1
}
}
// 将 arr[left......i - 1] 向右移动一格
for j := i; j > left; j-- {
arr[j] = arr[j-1]
}
arr[left] = tem
}
}
二路插入排序