插入排序(insertSort)

直接插入排序
算法思路:
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
	}
}

二路插入排序

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值