【归并排序】C语言实现归并排序

本文详细介绍了归并排序的基本思想、递归版代码实现以及非递归版两种方法,包括升序排序过程和代码演示。重点展示了如何通过分治策略将数组分割、排序和合并的过程。
摘要由CSDN通过智能技术生成

1.基本思想

归并排序(MERGE–SORT)是建立在归并操作上的一种有效的排序算法该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

归并排序核心步骤(升序排序):
在这里插入图片描述

2.递归版–代码实现

升序排序
步骤:
比照函数,一步一步分析

  1. mid = 3
  2. left1 = 0, right1 = 3, left2 = 4 ,right2 = 7
  3. MergeSort(arr, a,0, 3)
  4. mid = 1
  5. left1 = 0, right1 = 1, left2 = 2 ,right2 = 3
  6. MergeSort(arr, a,0, 1)
  7. mid = 0
  8. left1 = 0, right1 = 0, left2 = 1 ,right2 = 1
  9. MergeSort(arr, a,0, 0)
  10. if (left >= right) return;
  11. MergeSort(arr, a, 1, 1)
  12. if (left >= right) return;
  13. i = 0
  14. 进入第一个 while 循环 ,arr[0]>arr[1] , a[0] = arr[1]
  15. left1 <= right1, a[1] = arr[0]
  16. memcpy
  17. MergeSort(arr, a,2, 3)
//归并排序
void MergeSort(int* arr, int*a, int left, int right)
{
	//结束条件
	if (left >= right)
	{
		return;
	}
	int mid = (left + right) / 2;
	//分两组
	int left1 = left ,right1 = mid;
	int left2 = mid + 1, right2 = right;
	//调用自己
	MergeSort(arr, a,left1, right1);
	MergeSort(arr, a,left2, right2);
	//排序
	int i = left;
	while (left1 <= right1 && left2 <= right2)
	{
		if ( arr[left1] < arr[left2])
		{
			a[i++] = arr[left1++];
		}
		else
		{
			a[i++] = arr[left2++];
		}
	}
	//把没插入完的部分也插入进去
	while (left1 <= right1)
	{
		a[i++] = arr[left1++];
	}
	while (left2 <= right2)
	{
		a[i++] = arr[left2++];
	}
	memcpy(arr + left, a+left, sizeof(int)*(right - left + 1));
}

int main()
{
	int arr[] = {10,6,7,1,3,9,4,2};
	//产生一个存放数组
	int* a = (int*)malloc(sizeof(int) * (sizeof(arr) / sizeof(int)));
	MergeSort(arr, a, 0, sizeof(arr) / sizeof(int)-1);

	return 0;
}

3.非递归版–代码实现

(1)排序一段copy一段

递归函数是把数组分至为每组只有一个的数,把两组进行排序,接着排序进每组为只有2个的数
改成非递归后,直接先进行一个一个数比较,在两个两个的比较…
在这里插入图片描述
代码演示:

//排序一部分后立即拷贝此部分
void MergeSortNoR_1(int* arr, int *a,int left, int right ,int n)
{
	//先开始一组一个元数
	int gap = 1;
	while (gap <= n)
	{
		for (int i = 0; i < n; i+=gap*2)
		{
			int left1 = i, right1 = i + gap - 1;
			int left2 = i + gap, right2 = i + gap * 2 - 1;
			//越界处理
			if (right1 > n || left2 > n)
			{
				break;
			}
			if (right2 > n)
			{
				right2 = n;
			}
			int j = i;
			while (left1 <= right1 && left2 <= right2)
			{
				//判断大下
				if (arr[left1] < arr[left2])
				{
					a[j++] = arr[left1++];
				}
				else
				{
					a[j++] = arr[left2++];
				}
			}
			//没放完的继续放
			while (left1 <= right1)
			{
				a[j++] = arr[left1++];
			}
			while (left2 <= right2)
			{
				a[j++] = arr[left2++];
			}
			//排序一部分就拷贝一部分
			memcpy(arr + i, a + i, sizeof(int) *(right2-i+1) );
		}
		gap += gap;
	}
}

int main()
{
	int arr[] = { 9,8,7,6,5,4,3,2,1 };
	int* a = (int*)malloc(sizeof(int) * 9);
	
	MergeSortNoR_1(arr, a, 0, 8, 8);
	return 0;
}

(2)排序一遍后再拷贝

实录基本和上面的一样,越界处理不同

//排序一遍完后再拷贝
void MergeSortNoR_2(int* arr, int* a, int left, int right, int n)
{
	//先开始一组一个元数
	int gap = 1;
	while (gap <= n)
	{
		for (int i = 0; i < n+1; i += gap * 2)
		{
			int left1 = i, right1 = i + gap - 1;
			int left2 = i + gap, right2 = i + gap * 2 - 1;
			//越界处理
			if (right1 > n )
			{
			     right1 = n;  
				 left2 = n ;
				 right2 = n-1;
			}
			else if (left2 > n)
			{
				left2 = n ;
				right2 = n-1;
			}
			else if (right2 > n)
			{
				right2 = n;
			}
			int j = i;
			while (left1 <= right1 && left2 <= right2)
			{
				//判断大小
				if (arr[left1] < arr[left2])
				{
					a[j++] = arr[left1++];
				}
				else
				{
					a[j++] = arr[left2++];
				}
			}
			//没放完的继续放
			while (left1 <= right1)
			{
				a[j++] = arr[left1++];
			}
			while (left2 <= right2)
			{ 
				a[j++] = arr[left2++];
			}
		}
		//排序一遍后再拷贝
		memcpy(arr, a, sizeof(int) * (n+1));
		gap += gap;
	}
	return;
}

int main()
{
	int arr[] = { 9,8,7,6,5,4,3,2,1 };
	int* a = (int*)malloc(sizeof(int) * 9);
	
	MergeSortNoR_1(arr, a, 0, 8, 8);
	return 0;
}
  • 13
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值