插入排序
描述:
插入排序(英语:Insertion Sort)是一种简单直观的排序算法。
工作原理:
插入排序原理很简单,讲一组数据分成两组,我分别将其称为有序组与待插入组。每次从待插入组中取出一个元素,与有序组的元素进行比较,并找到合适的位置,将该元素插到有序组当中。就这样,每次插入一个元素,有序组增加,待插入组减少。直到待插入组元素个数为0。当然,插入过程中涉及到了元素的移动。
为了排序方便,我们一般将数据第一个元素视为有序组,其他均为待插入组。
演示:
1. 以数组{38,65,97,76,13,27,49}为例,
2.
3.
简洁版:
def insertion_sort(li): n = len(li) for i in range(n-1): for j in range(i+1, 0, -1): if li[j-1] > li[j]: li[j-1], li[j] = li[j], li[j-1] return li
注释版:
import random def insertion_sort(li): n = len(li) # 列表的长度 for i in range(n-1): # 控制内层循环执行的次数, 以及内层循环从第几个元素开始 # [i表示第几次执行内层循环, 也表示内层循环每次都从第几个元素开始, 进行比对 for j in range(i+1, 0, -1): # range(i+1, 0, -1)生成一个 i+1 , i , i-1, ....., 3, 2, 1这样的倒序序列 # 下面if判断语句, 根据range()函数产生的序列, 进行切片, 进行元素比对 # 从第j下标处开始切片, 两个元素进行比对, 如果前者大于后者交换顺序 # 循此往复, 比对到列表的第一个元素, 结束 if li[j-1] > li[j]: li[j-1], li[j] = li[j], li[j-1] return li if __name__ == "__main__": l = list(i for i in range(0, 10000)) print("洗牌之前的列表:" + str(l)) random.shuffle(l) print("洗牌之后的列表:" + str(l)) print("冒泡之后的列表:" + str(insertion_sort(l)))
时间复杂度
最优时间复杂度:O(n) (升序排列,序列已经处于升序状态)
最坏时间复杂度:O(n2)
稳定性:
稳定
插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。
当然,刚开始这个有序的小序列只有1个元素,就是第一个元素。
比较是从有序序列的末尾开始,也就是想要插入的元素和已经有序的最大者开始比起,如果比它大则直接插入在其后面,否则一直往前找直到找到它该插入的位置。
如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。
所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的
注意:
如果将判断条件
if li[j-1] > li[j]:
改为
if li[j-1] >= li[j]:
那么就是不稳定的了