二路归并排序
二路归并排序是采用的分而治之的思想。将一个待排序的序列分成两个序列,分别对这两个序列排序。而对于这两个序列排序的方式也是还之前一样,将这两个序列分别分成两个序列分别排序。一直这样分割下去,知道序列中没有元素或者已有一个元素为止。因为没有元素的序列和只有一个元素的序列定是一个有序的序列,所以相当于将这个序列排序完毕,向上返回。返回的过程中做的最重要的一件事就是将两个有序的序列合并成一个有序的序列。
所以归并排序最重要的两步是分割和合并。
例如:序列{50, 90, 30, 70, 40, 80, 60, 20}。这个序列进行二路归并排序的过程如下图所示:
int MergeSort(datatype *array, int low, int high)
{
int i, j, k;
int mid;
int *temp;
if(array == NULL) {
return -1;
}
if(low >= high) {
return -1;
}
//辅助数组存两个数组有序之后合并成为的一个有序的数组
temp = (int *)malloc(sizeof(int)*(high-low+1));
if(temp == NULL) {
return -1;
}
mid = (low + high) / 2;
//递归调用归并排序去是分割成的两个序列有序
MergeSort(array, low, mid);
MergeSort(array, mid+1, high);
//下面的程序是将两个有序的序列合并为一个有序的序列
i = low;
j = mid+1;
k = 0;
//i指向第一个数组当前的比较值,j指向第二个数组的比较值
while(i <= mid && j <=high) {
//比较i指向的值和j指向的值,将比较小的赋值给temp
if(array[i] < array[j]) {
temp[k++] = array[i++];
} else {
temp[k++] = array[j++];
}
}
//当i依旧小于mid时,相当于第一个序列还有剩余的一个或多个数据
//这些数肯定都是大于第二个序列的所有的数的。将这些数全部依次赋值给temp
while(i <= mid) {
temp[k++] = array[i++];
}
//当j依旧小于high时,相当于第一个序列还有剩余的一个或多个数据
//这些数肯定都是大于第一个序列的所有的数的。将这些数全部依次赋值给temp
while(j <= high) {
temp[k++] = array[j++];
}
//将temp中所保存的整个有序的序列赋值到原先序列的对应位置中
for(i = 0; i <= high-low; i++) {
array[low+i] = temp[i];
}
return 0;
}