归并排序算法

归并排序的基本思想:

归并排序使用了分治(即分开治理)和归并操作的思想。

例如将一个数组分成多块组成,通过递归完成对每一部分的分开,判断条件:Start>=End时即分完一部分,进行return跳出操作。在对每一部分进行归并操作,完成排序。

Step1:通过递归进行拆分;

Step2:进行归并排序;

示例代码:

void  MergeSort(int arr[], int start,int end)
{
	if (start>=end)
	//判断条件:可参考二分查找条件
	//注:取等号时,长度为1无法再分
	return;
	int mid = (start + end) / 2;//找到数组中间位置mid
	MergeSort(arr, start, mid);//对前一个数组进行归并排序
	MergeSort(arr, mid + 1,end);//对后一个数组进行归并排序
	Merge(arr, start, mid, end);
}

排序的过程,首先进行递归:

以一个长度为10的数组为例。Start初始为0,End初始为9,mid为(0+9)/2。

接下来对数组左侧开始进行递归:

将该数组进行赋值方便后续示例:

此时对0,1位置进行排序,需要临时开辟一个空间即一个长度为(end-start+1)的数组,利用该数组对原数组的分块进行排序,

注意:每次排序后都将临时空间的数放回原数组:

对该递归的上一步进行排序:

同理对上述操作的上一步进行排序:

此时左侧数组的排序已经完成了,右侧数组的排序和左侧排序的步骤相同:

直至最后一次归并过程:

至此归并排序全部排序完毕。

排序详细代码:

void Merge(int arr[], int start, int mid, int end)
{
	int* pArr = new int[end - start + 1];//开辟辅助空间
	int i = start;//左侧的部分起始下标
	int j = mid + 1;//右侧的部分起始下标
	int k = 0; //临时空间的数组pArr下标
	while (i<=mid && j<=end)
	{
		if (arr[i] < arr[j])
		{
			pArr[k] = arr[i];
			i++;
		}
		else
		{
			pArr[k] = arr[j];
			j++;
		}
		k++;
	} 
	while (i<=mid)//左侧没有走到结尾
	{
		pArr[k] = arr[i];
		i++;
		k++;
	} 
	while (j<=end)//右侧没有走到结尾
	{
		pArr[k] = arr[j];
		j++;
		k++;
	}
	//临时空间的数组已经排序完成了
	//将此数组传入原数组中
	i = start;
	k = 0; 
	while (k<end-start+1)
	{
		arr[i] = pArr[k];
		i++;
		k++;
	}
	delete[]pArr;
	pArr = nullptr;
}

 使用归并排序,先创建一个数组:

int arr[] = {5,4,7,5,4,2,5,7,9,7};

调用归并排序:

MergeSort(arr,0,9);

遍历原数组arr:

for (int nVal : arr)
{
	cout << nVal << " ";
}
cout << endl;

结果:

  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值