1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| ''' 归并算法排序 归并排序是稳定排序 "分而治之",再递归处理。 承接上一课中的 有序子列归并,使用 分而治之的思路, 先把数组分为左边和右边部分,分别排好顺序,再用有序子列归并,归并左、右部分。
'''
def M_Sort(A,temp_A,L,RightEnd ): if L < RightEnd: Center = (L + RightEnd)//2 M_Sort(A,temp_A,L,Center) M_Sort(A,temp_A,Center+1,RightEnd) Merge(A,temp_A,L,Center+1,RightEnd) ''' 注意!!!! 特意说明一个问题: 为什么要在M_Sort参数里带着temp_A 这个临时数组走, 而不是在M_Sort内部每次生成一个temp_A临时数组? 这是因为: 虽然他们的总的空间复杂度是一样的,但是每次在M_Sort内部生成一个临时数组又关掉, 递归中用到M_Sort,就会频繁开辟内存空间又清理内存空间,不合算。 最好的做法是一开始就生成一个temp_A临时数组,只把这个数组的指针传进整个工程中。 视频中陈老师的图解分析的非常直观。 '''
def Merge_Sort(A): N = len(A) temp_A = [None for _ in A] if temp_A!=None: M_Sort(A,temp_A,0,N-1) else: return "空间不足"
def Merge(A,TmpA,L,R,RightEnd): LeftEnd = R - 1 Tmp = L NumElements = RightEnd - L + 1 while L <= LeftEnd and R <= RightEnd: if A[L] < A[R]: TmpA[Tmp] = A[L] L += 1 else: TmpA[Tmp] = A[R] R += 1 Tmp += 1 while L <= LeftEnd: TmpA[Tmp] = A[L] Tmp += 1 L += 1 while R <= RightEnd: TmpA[Tmp] = A[R] Tmp += 1 R += 1 print(TmpA) for i in range(RightEnd,RightEnd-NumElements,-1): A[i] = TmpA[i]
if __name__ == '__main__': A = [1,5,6,2,4,3,8,9,7] Merge_Sort(A) print('上面的过程可以清晰的观察归并排序的过程\n',A)
|