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.插入排序分类
直接插入排序,二分插入排序(又称折半插入排序),链表插入排序,希尔排序(又称缩小增量排序)
属于稳定排序的一种(通俗地讲,就是两个相等的数不会交换位置)
作者:西伯尔
出处:http://www.cnblogs.com/sybil-hxl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。