首先来看merge函数
void merge(int arr[],int L,int M,int R){
int left_size=M-L;
int right_size=R-M+1;
int left[left_size];
int right[right_size];
int i,j,k ;
for (i=L;i<M;i++){
left[i-L]=arr[i];
}
for (i=M;i<=R;i++){
right[i-M]=arr[i];
}
i=0; j=0; k=L;
while(i<left_size && j < right_size){
if(left[i]<right[j]){
arr[k]=left[i];
i++;
k++;
}
else{
arr[k]=right[j];
j++;
k++;
}
}
while(i<left_size){
arr[k]=left[i];
i++;//先赋值、再自增
k++;
}
while(j<right_size){
arr[k]=right[j];
j++;
k++;
}
}
merge函数实现的是将已经排好序的两个小段组合成一个有序的大段;
如下所示:arr是有两个排好序的数组组成{2,5,9,10}以及{4,6,8,11},
通过merge函数,首先将其拆为两个数组:left和right
然后通过如下图所示比较,得到新的arr{2,4,5,6,8,9,10,11},具体操作如下图所示案例;
接着来看递归函数mergesoft()
void mergesoft(int arr[],int L,int R){
if(L==R){
return;
}
else{
int M=( L + R ) / 2 ;
mergesoft(arr, L, M);
mergesoft(arr, M+1, R);
merge(arr , L, M+1, R);
}
}
对于一个乱序数组来说,比如arr[]={2,5,3,9,7,4,1,8},归并排序采用的策略是将其不断分割成小的数组,知道分割为单个元素的数组,因为我们知道,单个的数组必然是有序的数组,这就是递的过程,归的过程就是在达到递归终止条件时(也就是将数组分割成单个元素的数组时),开始merge()函数的执行,首先将两个单元素数组merge(组合)成双元素且排好序的数组,接着将两个双元素且排好序的数组merge(组合)成四元素且排好序的数组,接着将两个四元素且排好序的数组merge(组合)成八元素且排好序的数组。
这里有关递归顺序并没讲的很清楚,如果想弄清楚递归的详细过程,可以看我的另一篇博客,
归并排序中的递归顺序详解
这里有详细的推导
c语言完整代码实现归并排序
#include <stdio.h>
void merge(int arr[],int L,int M,int R){
int left_size=M-L;
int right_size=R-M+1;
int left[left_size];
int right[right_size];
int i,j,k ;
for (i=L;i<M;i++){
left[i-L]=arr[i];
}
for (i=M;i<=R;i++){
right[i-M]=arr[i];
}
i=0; j=0; k=L;
while(i<left_size && j < right_size){
if(left[i]<right[j]){
arr[k]=left[i];
i++;
k++;
}
else{
arr[k]=right[j];
j++;
k++;
}
}
while(i<left_size){
arr[k]=left[i];
i++;//先赋值、再自增
k++;
}
while(j<right_size){
arr[k]=right[j];
j++;
k++;
}
}
void mergesoft(int arr[],int L,int R){
if(L==R){
return;
}
else{
int M=( L + R ) / 2 ;
mergesoft(arr, L, M);
mergesoft(arr, M+1, R);
merge(arr , L, M+1, R);
}
}
int main(){
int arr[]={2,5,3,9,7,4,1,8};
int L=0 ; int R=7;
mergesoft (arr,L,R);
int i;
for(i=0;i<=R;i++){
printf("%d ",arr[i]);
}
}
接下来附上java实现的代码
后面在补,不想写了
在这里插入代码片