希尔排序
算法步骤
- 将一个数组根据步长分成k个序列,放在一个表中
- 对列分别进行插入排序
- 重复这过程,不断减少步长,直到最后整个表只有一列
举个?
数组[ 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 ]
- 以步长5进行分割,得到:
13 14 94 33 82
25 59 94 65 23
45 27 73 25 39
10
- 对列进行插入排序
10 14 73 25 23
13 27 94 33 39
25 59 94 65 82
45
得到:[ 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 ]
- 以3为步长进行分割,得到:
10 14 73
25 23 13
27 94 33
39 25 59
94 65 82
45
对列进行插入排序:
10 14 13
25 23 33
27 25 59
39 65 73
45 94 82
94
- 最后以1步长进行插入排序
代码实现
def shell_sort(alist):
n = len(alist)
# 初始步长
gap = n // 2
while gap > 0:
# 按步长进行插入排序
for i in range(gap, n):
j = i
# 插入排序
while j>=gap and alist[j-gap] > alist[j]:
alist[j-gap], alist[j] = alist[j], alist[j-gap]
j -= gap
# 得到新的步长
gap = gap // 2
测试
alist = [54,26,93,17,77,31,44,55,20]
shell_sort(alist)
print(alist)
[17, 20, 26, 31, 44, 54, 55, 77, 93]
归并排序
算法步骤
- 申请空间,使其大小为两个已经排序序列之和
- 设定两个指针,最初位置分别为两个已经排序序列的起始位置
- 先递归分解数组,将列表越分越小,直至分成一个元素(这一个元素是有序的)
- 比较两个数组的最前面的数,取小的元素到之前申请的空间,取了后相应的指针就往后移一位,最后列表越来越大
图片详解
代码实现
import math
def MergeSort(arr):
if len(arr) < 2:
return arr
# 二分分解数组
num = math.floor(len(arr)/2)
left = MergeSort(arr[:num])
right = MergeSort(arr[num:])
# 合并
return Merge(left,right)
def Merge(left,right):
# 将两个有序数组left[],right[]合并成一个大的有序数组
l , r = 0 ,0 # left与right的下表指针
result= []
while l <len(left) and r < len(right):
if left[l] < right[r]:
result.append(left[l])
l += 1
else:
result.append(right[r])
r += 1
result += left[l:]
result += right[r:]
return result
测试
arr = [54,26,93,17,77,31,44,55,20]
sorted_arr = MergeSort(arr)
print(sorted_arr)
[17, 20, 26, 31, 44, 54, 55, 77, 93]