归并排序
归并排序中最重要的就是将两个已排序子数组进行归并,我们选择重复比较每个子数组得大小,将小的重新放置到原始组。在每个临时子数组的最后设置哨兵值,设置为一个特殊值INT_MAX,这样可以保障当一个子数组到达哨兵值后永远会将另一个子数组赋值给原数组,除非两个子数组都到达哨兵值。当这种情况出现,两个子数组均已被赋值给原数组,原数组已被合并为一个新的排序数组。
#include <stdio.h>
#include <limits.h>
void merge(int*arr,int p,int q,int r){
int n1=q-p+1;
int n2=r-q;
int left[n1+1];
int right[n2+1];
for(int i=0;i<n1;i++)
left[i]=arr[p+i]; //arr[p] 到 arr[q];
for(int j=1;j<=n2;j++)
right[j-1]=arr[q+j]; //arr[q+1]到arr[r];
left[n1]=INT_MAX;
right[n2]=INT_MAX;
int i=0,j=0;
for(int k=p;k<=r;k++){
if(left[i]<=right[j]){
arr[k]=left[i];
i++;
}
else{
arr[k]=right[j];
j++;
}
}
}
void mergeSort(int* arr,int p,int r){
int q;
if(p<r){
q=(p+r)/2;
mergeSort(arr,p,q);
mergeSort(arr,q+1,r);
merge(arr,p,q,r);
}
}
int main(void){
int arr[]={2,4,5,6,1,2,9,0};
mergeSort(arr,0,7);
for(int i=0;i<8;i++)
printf("%d ",arr[i]);
return 0;
}