归并排序算法

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/AMDDMA/article/details/87811691

一、算法核心

分区合并子函数

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;
 }

三、执行结果及解析

无序数组排序过程

有序数组排序过程

注:左右递归是对称执行的。

展开阅读全文

没有更多推荐了,返回首页