例题:利用归并排序方法对数字序列:5,19,17,21,11,8,1进行排序,共需要进行( )次比较
答案:11
程序:
def merge_sort(arr):
if len(arr)<=1:
return arr
mid = len(arr)//2 #坑仔这 分组出现问题
left = merge_sort(arr[:mid])
right = merge_sort(arr[mid:])
return merge(left,right)
def merge(left,right):
res = []
while left and right:
if left[0]<right[0]:
res.append(left.pop(0))
else:
res.append(right.pop(0))
res = res+left+right
return res
以上程序分析该题:
第一次分解: 7//2=3 (5,19,17) (21,11,8,1)
第二次分解: 3//2=1 (5) (19,17) 4//2 (21,11) (8,1)
第三次分解: 单个数字
第一次归并:(19,17)比较一次返回(17,19) (21,11)比较一次返回(11,21) (8,1)比较一次返回(1,8) 共3次
第二次归并:(5,17)比较一次left为空 结束比较 返回(5,17,19) (11,1)比较一次(11,8)比较一次 right为空 返回 (1,8,11,21) 共3次
第三次归并:(5,1)比较一次,(5,8)比较一次,(17,8)比较一次,(17,11)比较一次,(17,21)比较一次, (19,21)比较一次 left为空 返回(1,5,8,11,17,,19,21) 共6次
总共 12次
更改程序:
def merge_sort(arr): if len(arr)<=1: return arr mid = (len(arr)+1)//2 #坑仔这 分组出现问题 left = merge_sort(arr[:mid]) right = merge_sort(arr[mid:]) return merge(left,right) def merge(left,right): res = [] while left and right: if left[0]<right[0]: res.append(left.pop(0)) else: res.append(right.pop(0)) res = res+left+right return res
分析:
第一次分解: (7+1)//2=4 (5,19,17,21) (11,8,1)
第二次分解: (4+1)//2=2 (5,19) (17,21) (3+1)//2 (11,8) (1)
第三次分解: 单个数字
第一次归并:(5,19)比较一次返回(5,19) (17,21)比较一次返回(17,21) (11,8)比较一次返回(8,11) 共三次
第二次归并:(5,17)比较一次 (19,17)比较一次(19,21)比较一次 left为空 返回 (5,17,19,21) (8,1)比较一次 ringt为空 返回(1,8,11) 共4次
第三次归并:(5,1)比较一次,(5,8)比较一次,(17,8)比较一次,(17,11)比较一次 ringht为空 返回(1,5,8,11,17,,19,21) 共4次
总共 11次