什么是归并排序呢?来看看百度百科的解释
归并排序是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
那这是什么意思呢?看下图
就是先划分,然后再合并排序。很简单吧
#include <stdio.h>
#include <stdlib.h>
void print_arr(int [],int );
void merge_sort(int [],int );
void msort(int [],int [],int ,int );
void merge(int [],int [],int ,int ,int );
int main(void)
{
int arr[] = {9,5,2,7,12,4,3,1,11};
int n = 9;
print_arr(arr,n);
merge_sort(arr,n);
print_arr(arr,n);
return 0;
}
void merge(int arr[],int temparr[],int ks,int zj,int mw)
{
//标记左半区第一个未排序的元素
int l_pos = ks;
//标记右半区第一个未排序的元素
int r_pos = zj+1;
//临时数组元素下标
int pos = ks;
//合并
while(l_pos <= zj && r_pos <= mw)
{
if(arr[l_pos] < arr[r_pos]) //左半区元素更小
{
temparr[pos++] = arr[l_pos++];
}
else //右半区第一个元素更小
{
temparr[pos++] = arr[r_pos++];
}
}
//合并左半区剩余元素
while(l_pos <= zj)
{
temparr[pos++] = arr[l_pos++];
}
//合并右半区剩余元素
while(r_pos <= mw)
{
temparr[pos++] = arr[r_pos++];
}
//把临时数组中合并后的元素复制到原来的数组
while(ks<=mw)
{
arr[ks] = temparr[ks];
ks++;
}
}
void msort(int arr[],int temparr[],int ks,int mw)
{
if(ks < mw)//只有一个元素
{
int zj = (ks + mw) / 2; //中间点下标
//递归划分左半区
msort(arr,temparr,ks,zj);
//递归划分右半区
msort(arr,temparr,zj+1,mw);
//合并已经排序的部分
merge(arr,temparr,ks,zj,mw);
}
}
void merge_sort(int arr[],int n)
{
int* temparr = (int*)malloc(n*sizeof(int));
if(temparr)//申请成功
{
msort(arr,temparr,0,n-1);//0开始下标 ,n-1末尾下标
free(temparr);
}
else//申请失败
{
puts("申请失败");
return;
}
}
void print_arr(int arr[],int n)
{
int i;
for(i = 0;i < n;i++)
{
printf("%d ",arr[i]);
}
putchar('\n');
}