归并排序也是经典的使用分治法思想的代表算法之一。归并排序的效率很高,而且是一种稳定的排序。其总体的思想思路就是将待排序的元素分成大致相同的两个子集合,分别对两个子集合进行排序,最终将排序的子集合合并成排好序的总集合
归并排序c代码实现如下:
# include <stdio.h>
void mergeSort(int *arr,int i,int n,int *temp);
void mSort(int *arr,int i,int mid,int n,int*temp);
int main(void){
int i;
inttemp[10] = {0};
intarr[10] = {5,1,8,13,17,4,15,22,12,19}; //模拟待排序的元素
mergeSort(arr,0,9,temp);
for(i=0;i<10;i++){
printf("%d",arr[i]);
}
return 0;
}
void mergeSort(int *arr,int i,int n,int *temp){
int mid; //定义一个中间值
if(i<n){ //此时说明至少还有2个元素
mid =(i+n)/2; //取两个数字的中间值
mergeSort(arr,i,mid,temp); //扯分左边的数组
mergeSort(arr,mid+1,n,temp);//扯分右边的数组
mSort(arr,i,mid,n,temp); //合并排好序的数组
}
}
void mSort(int *arr,int i,int mid,int n,int*temp){
//temp数组就是一个临时数组,用来记录已经排好序的数组,然后赋给arr
int k =0;
int j =mid+1;
int first= i;
while(i<=mid&&j<=n){
if(arr[i]<= arr[j]){ //比如左边和右边数组的值,谁小的谁先放在temp数组中去
temp[k++]= arr[i++];
}else{
temp[k++]= arr[j++];
}
}
//有可能有一边还没有把数组全部放到temp中去,所以我们继续放完
while(i<=mid){
temp[k++]= arr[i++];
}
while(j<=n){
temp[k++]= arr[j++];
}
//然后把temp中的值对应的赋给arr
for(j=0;j<k;j++){
arr[first+j]= temp[j];
}
}
下面来看下归并排序的复杂度,因为归并排序每次都需要arr中的元素进行两两归并,
每次都需要把元素放到temp中,所以时间复杂度为o(n)。而归并排序从某种意义上来说又是一颗完全二叉树,由完全二叉树的知识可以知道整个归并排序的次数是logn次,所以总的时间复杂度是(nlogn)