1 什么叫插入排序
1.1 原理
- 插入排序(英语:Insertion Sort)是一种简单直观的排序算法。
- 它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
- 插入排序在实现上,在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
1.2 图解
2 插入排序和选择排序的关系
相同点:
- 都是将序列分为两部分,一部分是已排序,另一部分是未排序
不同点:
- 选择排序是将未排序部分元素的最小值 选择到排序部分的最后边,放到最后边的方式是通过交换未排序部分的最小值和给定位置的!
- 插入排序是将后面无序元素插入到有序数组中指定的位置,即后面无序部分不用找最小或者最大。
3 代码实现
思路:
- 也是将数据分为两部分,比如左边是已经排序的,右边是未排序的!
- 还是设置两个变量,一个是位置,一个是遍历左边已排序的元素,如果位置上元素小于左边的,互换元素,否则不动
- 循环遍历所有位置即可
for j in range(4-1,-1,-1):
print(j)
3
2
1
0
def insert_sort(alist):
'''插入排序'''
n = len(alist)
for i in range(1,n):
# 遍历无序序列的每一个位置
mix = i
for j in range(i-1,-1,-1):
# 遍历有序的每一个位置 从右到左
if alist[mix] < alist[j]:
alist[mix], alist[j] = alist[j], alist[mix]
mix = j # 因为是要交换后元素进一步和之前的比较
else:
break # 如果选定的值大于左边有序的最右边的 则不动 即不用遍历 故直接跳出循环
# break加上 可以减小时间复杂度 如果已经有序后
return alist
alist = [54,26,93,17,77,31,44,55,20]
insert_sort(alist)
[17, 20, 26, 31, 44, 54, 55, 77, 93]
增大样本量试试:
li2 = []
for i in range(10000):
li2.append(np.random.randint(10000))
li2[:10]
[4906, 7051, 7216, 5706, 3346, 2059, 4233, 4997, 2077, 7177]
insert_sort(li2)[:20]
[0, 0, 1, 1, 1, 1, 3, 5, 6, 6, 7, 9, 10, 12, 13, 15, 16, 16, 19, 20]
4 时间复杂度
- 最坏时间复杂度:双重循环,故为O( n 2 n^2 n2)
- 最优时间复杂度:已经为有序的序列了,所以只用一个循环线性遍历即可,故为O( n n n)
5 算法稳定性
稳定的!
为啥呢?因为无序部分如果不小于前面有序的最后一个,那么就不用进行插入操作了,所以相同元素还是保持原有的顺序!所以是稳定的!