一、插入排序(insertion sort)
将数组中的数据分为两个区间,已排序区间和未排序区间。初始已排序区间只有一个元素,就是数组的第一个元素。插入算法的核心思想是取未排序区间中的元素,在已排序区间中找到合适的插入位置将其插入,并保证已排序区间数据一直有序。重复这个过程,直到未排序区间中元素为空,算法结束。(抓扑克牌形式)
插入排序包含元素的比较和元素的移动。将一个数据 a 插入到已排序区间时,需要拿 a 与已排序区间的元素依次比较大小,找到合适的插入位置。找到插入点之后,还需要将插入点之后的元素顺序往后移动一位,这样才能腾出位置给元素 a 插入。
# 插入排序
'''
将数组中的数据分为两个区间,已排序区间和未排序区间。初始已排序区间只有一个元素,就是数组的第一个元素。
插入算法的核心思想是取未排序区间中的元素,在已排序区间中找到合适的插入位置将其插入,并保证已排序区间数据一直有序。
重复这个过程,直到未排序区间中元素为空,算法结束。
(抓扑克牌形式)
'''
'''
li = [3, 4,57,32,13,46,21,55,77,0,6]
0 1 2 3...
li = [0, 3, 4, 57,32,13,46,21,55,77,6]
j-2 j-1 j i i+1...
'''
li = [3,4,57,32,13,46,21,55,77,0,6]
def insert_sort():
for i in range(1, len(li)): # 从第2个开始循环,因为列表第一个元素默认排序完成
for j in range(i, 0, -1): # 未排序列的第一个元素i,排序之后的最后一个元素j,需要倒叙循环
if li[j] < li[j-1]: # 需要和排序完成的j数列进行比较大小
li[j], li[j-1] = li[j-1], li[j] # 交换数值
print(li)
insert_sort()
插入排序算法是稳定算法,它的时间复杂度是O(n).
二、希尔排序(shell sort)
希尔排序,也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。
运行原理:先选取数组长度n除以2的步长gap(gap = len(li) // 2),拆分成不同的几组数列,分别各自组进行排序,然后缩小步长(gap = gap // 2),继续分为几组,每组各自排序,直到gap缩小为1,此时分成一组数列进行排序,完成就是要得到的有序数组。
# 希尔排序
'''
[3, 4, 57, 32, 13, 46, 21, 55, 77]
3 13 77
4 46
57 21
32 55
上面是gap=4时候,将数组拆分成不同的几组数列,单独排序 ,排序完成之后是
3 13 77
4 46
21 57
32 55
3 4 21 32 13 46 57 55 77
然后gap//2=2,继续拆分为:
3 21 13 57 77
4 32 46 55
排序结果为:
3 13 21 57 77
4 32 46 55
3 4 13 32 21 46 57 55 77
gap//2=1,继续排序为:
3 4 13 21 32 46 55 57 77
完成希尔排序
'''
li = [3,4,57,32,13,46,21,55,77]
def shell_sort():
gap = len(li) // 2 # python3中9/2=4.5 9//2=4 四舍六入五成双
while gap > 0: # gap不断缩小,等于1的时候,排序完成
for i in range(gap, len(li)): # 循环从gap开始,是为了容易写li[i-gap]和li[i]代表元素
while i >= gap and li[i-gap] > li[i]: #
li[i-gap],li[i] = li[i], li[i-gap] # 数据交换
i -= gap # 不同的组别,进行不同的排序 所以i的值根据gap来改变
gap = gap // 2 # 缩小gap直到为1
print(li)
shell_sort()
“四舍六入五成双”规则如下:
“四舍六入五成双”,也即“4舍6入5凑偶”,这里“四”是指≤4 时舍去,"六"是指≥6时进上。"五"指的是根据5后面的数字来定,当5后有数时,舍5入1;当5后无有效数字时,需要分两种情况来讲:5前为奇数,舍5入1;5前为偶数,舍5不进(0是偶数)。
一、具体计算规则:
(1)被修约的数字小于5时,该数字舍去;
(2)被修约的数字大于5时,则进位;
(3)被修约的数字等于5时,要看5前面的数字,若是奇数则进位,若是偶数则将5舍掉,即修约后末尾数字都成为偶数;若5的后面还有不为“0”的任何数,则此时无论5的前面是奇数还是偶数,均应进位。
希尔排序算法时间复杂度
最优时间复杂度:根据步长序列的不同而不同
最坏时间复杂度:O(n^2)