归并排序
时间复杂度:
1 /* L = 左边起始位置,R = 右边起始位置, RightEnd = 右边中点位置 */ 2 void Merge(ElementType A[], ElementType TmpA[], int L, int R, int RightEnd) 3 { 4 /* 将有序的A[L]-A[R-1]和A[R]-A[][RightEnd]归并成一个有序序列 */ 5 6 int OriginalL = L; //记录L的初始位置,以便于最后将TmpA[]复制回A[] 7 int LeftEnd, NumElements, Tmp; 8 int i; 9 10 LeftEnd = R-1; /* 左边终点位置 */ 11 Tmp = L; /* 有序序列的起始位置 */ 12 NumElements = RightEnd-L+1; /* 总的归并的元素个数 */ 13 14 while(L <= LeftEnd && R <= RightEnd) 15 { 16 if(A[L] <= A[R]) 17 { 18 TmpA[Tmp] = A[L]; /* 将左边元素复制到TmpA */ 19 ++Tmp; 20 ++L; 21 } 22 else 23 { 24 TmpA[Tmp] = A[R]; /* 将右边元素复制到TmpA */ 25 ++Tmp; 26 ++R; 27 } 28 } 29 30 while(L <= LeftEnd) 31 { 32 TmpA[Tmp] = A[L]; /* 复制左边剩下的 */ 33 ++Tmp; 34 ++L; 35 } 36 while(R <= RightEnd) /* 复制右边剩下的 */ 37 { 38 TmpA[Tmp] = A[R]; 39 ++Tmp; 40 ++R; 41 } 42 43 for(i = OriginalL; i < NumElements; ++i) 44 A[i] = TmpA[i]; /* 将有序的TmpA[]复制回A[] */ 45 46 } 47 48 /* 核心递归排序函数 */ 49 void Msort(ElementType A[], ElementType TmpA[], int L, int RightEnd) 50 { 51 int Center; 52 53 if(L < RightEnd) 54 { 55 Center = (L + RightEnd) / 2; 56 Msort(A, TmpA, L, Center); /* 递归解决左边 */ 57 Msort(A, TmpA, Center+1, RightEnd); /* 递归解决右边 */ 58 Merge(A, TmpA, L, Center+1, RightEnd); /* 合并两段有序序列 */ 59 } 60 } 61 62 63 /* 归并排序 */ 64 void MergeSort(ElementType A[], int N) 65 { 66 ElementType *TmpA; 67 TmpA = (ElementType *)malloc(N*sizeof(ElementType)); 68 69 Msort(A, TmpA, 0, N-1); 70 free(TmpA); 71 }
注意:
在MergeSort中定义TmpA临时数组,可以使整个过程只申请释放空间一次,空间复杂度为O(N) ,如果在Merge函数里定义TmpA数组的话,整个过程将反复malloc与free,使得空间复杂度变为O( NlogN)。