八大排序(3)------归并排序

思想:

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

总而言之,归并排序总体分为两步:分解与合并
先分解为许多有序的子区间,然后再将这些有序的子区间合并成一个有序区间。见如下图所示:
在这里插入图片描述
因此,我们在实现该算法时就分为三步:

  1. 将区间划分为两部分
  2. 将这两部分分为有序的子区间
  3. 将子区间合并成一个有序区间

首先,我们先将整体思路来实现一下,具体如何分解如何合并我们后面一一分析:
代码实现:

public void mergeSortInternal(int[] array, int low, int high) {
	if(low >= high)
	{
		return ;
	}
	//分割为两部分
	int par=(low+high)/2;
	mergeSortInternal(array,low,par);
	mergeSortInternal(array,par+1,high);

	//合并
	merge(array,low,par,high);
}

上面代码就是归并排序的思路,也就是上面说的三步:分为两个区间,分解,合并。
接下来就来看看如何将有序区间进行合并的:

merge方法:
先说一下合并方法的思想:

  • s1和s2分别从两个区间首元素开始;
  • 比较s1和s2对应的元素谁小将谁放到临时数组中并且让下标++,直到所有元素比较完;
  • 如果有一个区间还剩有元素,直接添加到临时数组尾部;
  • 最后将临时数组中的元素全部搬移到原始数组中;

注意: 搬移元素的时候需要搬移回原位置,从 low 开始(low是原始数组的下标)

我们以上图中6 10和1 7两个区间为例,假设s1代表第一个区间的起始下标(也就是参数low),s2代表第二个区间的起始下标(也就是参数par+1);具体过程如下图所示:
在这里插入图片描述

代码实现:

private void merge(int[] array, int low, int par, int high) {
	int s1=low;
	int s2=par+1;
	int length=high-low+1;
	int [] tmp=new int[length];
	int i=0;//临时数组的下标
	
	//两个区间都有元素
	while(s1<=par && s2<=high)
	{
		if(array[s1]<=array[s2])
		{
			tmp[i++]=array[s1++];
		}else{
			tmp[i++]=array[s2++];
		}
	}
	//只有s1区间有元素
	while(s1<=par)
	{
		tmp[i++]=array[s1++];
	}
	//只有s2区间有元素
	while(s2<=high)
	{
		tmp[i++]=array[s2++];
	}

	//搬移元素
	for(int j=0;j<length;j++)
	{
	 // 需要搬移回原位置,从 low 开始
		array[j+low]=tmp[j];
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值