插入排序

插入排序

描述:

插入排序(英语: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
View Code

 

注释版:

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)))
View Code

 

时间复杂度

最优时间复杂度:O(n) (升序排列,序列已经处于升序状态)
最坏时间复杂度:O(n2)

稳定性:

稳定

插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。
当然,刚开始这个有序的小序列只有1个元素,就是第一个元素。
比较是从有序序列的末尾开始,也就是想要插入的元素和已经有序的最大者开始比起,如果比它大则直接插入在其后面,否则一直往前找直到找到它该插入的位置。
如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。
所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的

注意:

如果将判断条件

if li[j-1] > li[j]:

改为

if li[j-1] >= li[j]:

那么就是不稳定的了

 

posted @ 2018-05-05 13:56  阿谋  阅读(171)  评论(0编辑  收藏  举报