假设有这样一个序列: 1 3 5 7 2 4 6 8. 将这个序列从中间一分为二,会发现,左边的序列是有序的,右边的序列也是有序的,但是整个序列是无序的,如果要使整个序列有序,可以借助一个临时数组,两个指向左右两个序列前边的指针 begin1 和 begin2(现在 begin1 指向1,begin2 指向2)。将左右两个序列的元素逐个比大小,小的进入临时数组,并且指针往后走一位。这样便可以用临时数组使整个序列有序。
上边所给的序列是从序列中间分开左右序列都有序。那如果左右是无序的该怎么办?可以将左右序列按照上边的办法,再一分为二进行处理……如果一直是无序的,最终会拆分成只有两个元素的一个序列,左右序列只有一个元素,一个元素肯定有序,操作完会返回给上一次拆分的位置,再操作,再返回给上上一次拆分的位置……
用一张图来演示,大概是这么个情况:
源码:
void MergeSort(int *a, int begin, int end, int *tmp) {
if (begin >= end)
return;
int mid = (begin + end) >> 1; // 向右移一位,相当于是除以 2
MergeSort(a, begin, mid, tmp);
MergeSort(a, mid + 1, end, tmp);
int begin1 = begin, end1 = mid;
int begin2 = mid + 1, end2 = end;
int index = begin; // tmp 临时数组的下标
while (begin1 <= end1 && begin2 <= end2) {
if (a[begin1] < a[begin2])
tmp[index++] = a[begin1++];
else
tmp[index++] = a[begin2++];
}
// 有可能一个序列已经为空,另一个还有元素
if (begin1 <= end1) {
while (begin1 <= end1)
tmp[index++] = a[begin1++];
}
else {
while (begin2 <= end2)
tmp[index++] = a[begin2++];
}
memcpy(a + begin, tmp + begin, sizeof(int)*(end - begin + 1));
}
void _MergeSort(int *a,int n) {
int* tmp = (int*)malloc(sizeof(int) * n);
MergeSort(a,0,n-1,tmp);
free(tmp);
}