# 归并排序算法

## 一、算法核心

### 分区合并子函数

void merge_sub_fun(int* src,int low,int high)
{
int i = low;
int mid = low + (high-low)/2;
int j= mid + 1;
int k = 0;
int tmp[high-low+1];
static int mp=1;
int* record_point = NULL;

/* 入参检查及临时缓存申请 */
if(NULL == src)
{
printf("Function:%s Malloc Failed!\n",__FUNCTION__);
return;
}
memset(tmp,0,sizeof(tmp));

/* 按照大小顺序合并两个有序分区 */
while(i <= mid && j <= high)
{
if(src[i] <= src[j])
tmp[k++] = src[j++];
else
tmp[k++] = src[i++];
}

/* 将剩余的参数拷贝 */
while(i <= mid)
tmp[k++] = src[i++];
while(j <= high)
tmp[k++] = src[j++];

/* 局部排序完成数据拷贝到原始数组中 */
for(i=low,k=0;i<= high;i++,k++)
src[i] = tmp[k];

record_point = (int*)malloc(sizeof(int)*merge_length);
if(NULL == record_point)
{
printf("Func:%s Malloc Failed!\n",__FUNCTION__);
}
else
{
memset(record_point,0,sizeof(int)*merge_length);
memcpy(record_point,src,sizeof(int)*merge_length);
merge_point[mp] = record_point;
mp++;
}
}

### 上级分区函数：递归实现

void merge_sort(int* src, int low, int high)
{
int mid;

if(NULL == src)
{
printf("Func:%s Input Err!\n",__FUNCTION__);
return;
}

if(low < high)
{
mid = low + (high-low) / 2;     /* 查找当前分区的中间位置 */
merge_sort(src, low, mid);
merge_sort(src, mid+1, high);
merge_sub_fun(src,low,high);
}
}

## 二、应用示例

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int** merge_point = NULL;
int merge_length = 0;

/* 格式化打印数组的数值 */
void printf_str(int *src,int length)
{
int i=0;

if(NULL == src || 0 == length)
{
printf("Func:%s Input Err:src=%d length=%d\n\r",src,length);
return ;
}

printf("数组元素:");
for(i=0;i<length;i++)
{
printf("   %2d",src[i]);
}
printf("\n\r");
}

/* 归并排序的底层排序、合并有序分区函数 */
void merge_sub_fun(int* src,int low,int high)
{
int i = low;
int mid = low + (high-low)/2;
int j= mid + 1;
int k = 0;
int tmp[high-low+1];
static int mp=1;
int* record_point = NULL;

/* 入参检查及临时缓存申请 */
if(NULL == src)
{
printf("Function:%s Malloc Failed!\n",__FUNCTION__);
return;
}
memset(tmp,0,sizeof(tmp));

/* 按照大小顺序合并两个有序分区 */
while(i <= mid && j <= high)
{
if(src[i] <= src[j])
tmp[k++] = src[j++];
else
tmp[k++] = src[i++];
}

/* 将剩余的参数拷贝 */
while(i <= mid)
tmp[k++] = src[i++];
while(j <= high)
tmp[k++] = src[j++];

/* 局部排序完成数据拷贝到原始数组中 */
for(i=low,k=0;i<= high;i++,k++)
src[i] = tmp[k];

record_point = (int*)malloc(sizeof(int)*merge_length);
if(NULL == record_point)
{
printf("Func:%s Malloc Failed!\n",__FUNCTION__);
}
else
{
memset(record_point,0,sizeof(int)*merge_length);
memcpy(record_point,src,sizeof(int)*merge_length);
merge_point[mp] = record_point;
mp++;
}
}

/* 递归方式实现排序 */
void merge_sort(int* src, int low, int high)
{
int mid;

if(NULL == src)
{
printf("Func:%s Input Err!\n",__FUNCTION__);
return;
}

if(low < high)
{
mid = low + (high-low) / 2;     /* 查找当前分区的中间位置 */
merge_sort(src, low, mid);
merge_sort(src, mid+1, high);
merge_sub_fun(src,low,high);
}
}

/* 用于显示、提示排序过程的数据 */
void merge_sort_function(int* src,int length)
{
int* record_point = NULL;
int i = 0;

if(NULL == src)
{
printf("Func:%s Input Err!\n",__FUNCTION__);
return;
}

merge_point = (int**)malloc(sizeof(int*)*length);
if(NULL == merge_point)
{
printf("Func:%s Malloc Failed!\n",__FUNCTION__);
}
else
{
memset(merge_point,0,sizeof(int*)*length);
record_point = (int*)malloc(sizeof(int)*length);
if(NULL == record_point)
{
printf("Func:%s Malloc Failed!\n",__FUNCTION__);
}
memcpy(record_point,src,sizeof(int)*length);
merge_point[0] = record_point;
}

merge_length = length;
printf("******归并排序算法详解*******\n排序前:");
printf_str(src,length);
printf("共%d个元素，开始排序......\n");
merge_sort(src,0,length-1);
printf("排序结果");
printf_str(src,length);
printf("排序过程详解:\n");
printf("**原始数组:");
printf_str(merge_point[0],length);
if(NULL != merge_point[0])
{
free(merge_point[0]);
merge_point[0] = NULL;
}

for(i=1;i<length;i++)
{
if(NULL != merge_point[i])
{
printf("第%2d次排序:",i);
printf_str(merge_point[i],length);
if(NULL != merge_point[i])
{
free(merge_point[i]);
merge_point[i] = NULL;
}
}
}

if(NULL != merge_point)
{
free(merge_point);
merge_point = NULL;
}
}

/* 两组不同的数组进行排序验证 */
int main()
{
int a[] = {93,100, 50, 10, 20, 30, 70, 40, 80, 60};
int src[] = {10,20,30,40,50,60,74,80};

//merge_sort_function(a,sizeof(a)/sizeof(int));

merge_sort_function(src,sizeof(src)/sizeof(int));

return 0;
}