插入排序法的实现,这里做了两种实现(思想是一样的):
- 一种是从前向后排,把后面的无序序列,插入到前面的有序序列
- 一种是从后向前排,把前面的无序序列,插入到后面的有序序列
废话不多说,直接上代码,下面代码已经经过调试,拿过去可以直接运行:
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File : sort_by_insertion.py
@Contact : buweiqiang@civaonline.cn
@MTime : 2020-12-21 17:21
@Author: buweiqiang
@Version: 1.0
@Desciption: 插入排序法思想:假设已经有一个有序序列,将未排序的数组,逐个个的插入到有序序列的合适位置
'''
import random
import time
def sort_forward(array: list):
'''
正序插入:假设第一位是有序序列,从第二位开始迭代,依次将后面的数字,插入到前面的有序序列
方法:假设第一位i=0是有序序列,从i+1开始,每次取有序序列后面位置的一个数j=i+1,将这个数与前面的有序序列(长度为i+1)向前逐个比较,如果比前面的小,就与之交换(即永远将小的数插入到大数的前面),如果不比前面的小,就可以中止退出本次循环
:param array: 未排序的数组
:return: 无
'''
n = len(array)
for i in range(n - 1):
# 从第二位开始,第一轮过后,前二位是有序序列,第二轮后,前三位是有序序列,以次类推,直到整个数组排序完成
j = i + 1
swap_count = 0 # 记录交换次数
while j > 0:
if array[j] < array[j - 1]:
temp = array[j]
array[j] = array[j - 1]
array[j - 1] = temp
j -= 1
swap_count += 1
else:
# 因为前面已经是有序序列,所以只要出现了一个数不比后面的小,就可以中止比较了,这点与比冒泡排序要好,不用每次都遍历到末尾
break
print(f'round {i + 1}, swap_count={swap_count}: {array}')
def sort_backward(array: list):
'''
倒序插入:假设倒数第一位是有序序列,从倒数第二位开始迭代,依次将前面的数字,插入到后面的有序序列
方法:假设最后一位n-1是有序序列,i=1~n,从n-1-i开始,每次取有序序列前面位置的一个数j=n-1-i,将这个数与后面的有序序列(长度为i)逐个比较,如果比后面的大,就与之交换(即永远将大的数插入到小数的后面),如果不比后面的大,就可以中止退出本次循环
:param array: 未排序的数组
:return: 无
'''
n = len(array)
for i in range(1, n):
# 从倒数第二位开始,第一轮过后,倒数二位是有序序列,第二轮后,倒数三位是有序序列,以次类推,直到整个数组排序完成
j = n - 1 - i
swap_count = 0
while j < n - 1:
if array[j] > array[j + 1]:
temp = array[j]
array[j] = array[j + 1]
array[j + 1] = temp
j += 1
swap_count += 1
else:
# 因为后面已经是有序序列,所以只要出现了前一个数不比后面的大,就可以中止比较了,这点与比冒泡排序要好,不用每次都遍历到末尾
break
print(f'round {i + 1}, swap_count={swap_count}: {array}')
if __name__ == "__main__":
array = [5, 7, 8, 5, 9, 3, 2, 10, 1, 13, 10]
# 如需做性能测试,把数组变长和循环次数加大即可
# array = [random.randint(0, 1000) for i in range(20)]
print(array)
# 正排
start_time = time.time()
for i in range(1):
sort_forward(array.copy())
end_time = time.time()
duration = end_time - start_time
print(f'duration of forward insertion: {duration}')
# 倒排
start_time = time.time()
for i in range(1):
sort_backward(array.copy())
end_time = time.time()
duration = end_time - start_time
print(f'duration of backward insertion: {duration}')
贴一下输出:
/usr/local/bin/python3.7 /Users/boweqiang/xxw/AutotestCornerstone/common/sort_by_insertion.py
[5, 7, 8, 5, 9, 3, 2, 10, 1, 13, 10]
round 1, swap_count=0: [5, 7, 8, 5, 9, 3, 2, 10, 1, 13, 10]
round 2, swap_count=0: [5, 7, 8, 5, 9, 3, 2, 10, 1, 13, 10]
round 3, swap_count=2: [5, 5, 7, 8, 9, 3, 2, 10, 1, 13, 10]
round 4, swap_count=0: [5, 5, 7, 8, 9, 3, 2, 10, 1, 13, 10]
round 5, swap_count=5: [3, 5, 5, 7, 8, 9, 2, 10, 1, 13, 10]
round 6, swap_count=6: [2, 3, 5, 5, 7, 8, 9, 10, 1, 13, 10]
round 7, swap_count=0: [2, 3, 5, 5, 7, 8, 9, 10, 1, 13, 10]
round 8, swap_count=8: [1, 2, 3, 5, 5, 7, 8, 9, 10, 13, 10]
round 9, swap_count=0: [1, 2, 3, 5, 5, 7, 8, 9, 10, 13, 10]
round 10, swap_count=1: [1, 2, 3, 5, 5, 7, 8, 9, 10, 10, 13]
duration of forward insertion: 8.797645568847656e-05
round 2, swap_count=1: [5, 7, 8, 5, 9, 3, 2, 10, 1, 10, 13]
round 3, swap_count=0: [5, 7, 8, 5, 9, 3, 2, 10, 1, 10, 13]
round 4, swap_count=1: [5, 7, 8, 5, 9, 3, 2, 1, 10, 10, 13]
round 5, swap_count=1: [5, 7, 8, 5, 9, 3, 1, 2, 10, 10, 13]
round 6, swap_count=2: [5, 7, 8, 5, 9, 1, 2, 3, 10, 10, 13]
round 7, swap_count=3: [5, 7, 8, 5, 1, 2, 3, 9, 10, 10, 13]
round 8, swap_count=3: [5, 7, 8, 1, 2, 3, 5, 9, 10, 10, 13]
round 9, swap_count=4: [5, 7, 1, 2, 3, 5, 8, 9, 10, 10, 13]
round 10, swap_count=4: [5, 1, 2, 3, 5, 7, 8, 9, 10, 10, 13]
round 11, swap_count=3: [1, 2, 3, 5, 5, 7, 8, 9, 10, 10, 13]
duration of backward insertion: 8.20159912109375e-05
Process finished with exit code 0