1.python实现直接插入排序算法(2种写法)

参考动图:

https://ask.qcloudimg.com/http-save/developer-news/fhf3o8po46.gif 

# 非递归写法
arr = [9, 5, 3, 2, 1, -9, 4]
for i in range(1, len(arr)):  # 外层循环为(n-1)*i*O(1),即为O(n^2)
    j = i
    key = arr[i]
    # 当前为i,逆序则向后移动一位,直到不满足的那个j,退出循环
    while j > 0 and key < arr[j - 1]:  # 一次比较为O(1),内层循环为i*O(1)
        arr[j] = arr[j - 1]  # 所谓插入的实现,其实是本步先后移,跳出内循环后再赋值
        j = j - 1
    arr[j] = key  # 每次赋值为一趟,共n-1趟,每趟向前比较,最多比较i次
print(arr)
# 递归写法(2种,i递增和递减)
# 递归体:前面有序序列跟当前数key=arr[i]排序(用循环可以,递归还没想好)
# 递归出口:应该是达到长度,直接返回,而不是减到0再比较
# 问题所在:i从0递增或者从len(arr)递减都可以
#         关键是,递减时,应该先递归进入,后递归体,再递归返回;
#                递增时,先递归体执行,后递归返回
# i递增
arr = [9, 5, 3, 2, 1, -9, 4]


def rsort(i):
    # print(i, arr)#用于显示递归栈的输出
    if i >= len(arr):
        return
    # 排列key和有序序列
    j = i
    key = arr[i]
    while j > 0 and key < arr[j - 1]:  # i*O(1)
        # print("后移")
        arr[j] = arr[j - 1]
        j = j - 1
    arr[j] = key
    # print(j)
    rsort(i + 1)  # T(n-1)


rsort(0) # T(n) = T(n-1)+i*O(1) = T(n-1)+n=T(n-2)+n-1+n=1+...+n-1 = n(n-1)/2=O(n^2)
 print(arr)
# i递减:
arr = [9, 5, 3, 2, 1, -9, 4]


def rsort(i):
    # print(i, arr)#用于显示递归栈的输出
    if i > 0:
        rsort(i - 1)  # T(n-1)
    # 排列key和有序序列
    j = i
    key = arr[i]
    while j > 0 and key < arr[j - 1]:  # i*O(1)
        # print("后移")
        arr[j] = arr[j - 1]
        j = j - 1
    arr[j] = key
    # print(j)


rsort(len(arr) - 1)  #T(n) = T(n-1)+i*O(1) = T(n-1)+n=T(n-2)+n-1+n=1+...+n-1 = n(n-1)/2=O(n^2)
 print(arr)

 

2.时间复杂度分析

(1)非递归

while j > 0 and a < arr[j - 1]:  # 一次比较为O(1),内层循环为i*O(1)
for i in range(1, len(arr)):  # 外层循环为(n-1)*i*O(1),即为O(n^2)

(2)递归(以i递增为例)

while j > 0 and key < arr[j - 1]:  # i*O(1)
rsort(i + 1)  # T(n-1)
rsort(len(arr) - 1)  # T(n) = T(n-1)+i*O(1) = T(n-1)+n=T(n-2)+n-1+n=1+...+n-1 = n(n-1)/2=O(n^2)

 

3.插入排序分类

直接插入排序,二分插入排序(又称折半插入排序),链表插入排序,希尔排序(又称缩小增量排序)

属于稳定排序的一种(通俗地讲,就是两个相等的数不会交换位置)

posted on 2019-09-17 22:16  西伯尔  阅读(381)  评论(0编辑  收藏  举报