归并排序(数组指针详细讲解,图例分析)

归并排序
思路:依照分治模式
分解:将n个元素分成各含n/2个元素的子序列;
解决:对两个子序列递归地排序
合并:合并两个已排序的序列的子序列以得到排序结果
和快排区别:
归并的分解较为随意,重点是合并
在这里插入图片描述
对下列数组元素进行排序
在这里插入图片描述
两边数组各自进行排序
特殊情况当出现右区间数组元素个数比左区间元素个数多时,可以不用管
还有一种特殊情况当出现左区间数组元素个数比右区间元素个数多时
伪代码

MergerSort
  mergeSort(A,p,r){  //数组A,左指针p,右指针r 
  	if(p<r){   //左指针指的元素小于右指针指的元素 
  		mid=p+((r-p)>>1);  //找中间值 
		  mergeSort(A,p,mid);  //左区间 
		  mergeSort(A,mid+1,r);  //右区间 
		  merge(A,p,mid,r);    //整个数组 
	  }
  } 
  helper=[A.length];    //开辟一个和原数组长度相同的辅助区间 
  merge(A,p,mid,r){   
  copy(A,p,helper,p,r-p+1){  //先把A中的数据拷贝到helper中
  	left=p  //左侧队伍的头部指针,指向待比较的元素
	  right=mid+1  //右侧队伍的头部指针,指向待比较元素
	  current=p  //原数组的指针,指向待填入数据的
	  
	  while(left<=mid&&right<=r){    //左边走的块,已经到头 
	  	if(helper[left]<=helper[right]){
	  		A[current]=helper[left];
	  		current++;
	  		left++;
		  }
		  else{
		  	A[current]=helper[right];
		  	current++;
		  	right++;
		  }
	  } 
	  if(left<=mid){
	  	A[current]=helper[left];
	  	current++;
	  	left++;
	  }
  } 
  } 

代码

package mergesort;

import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util;

public class Mergesort {
	private static int[] helper;  //开辟一个辅助空间
    helper=new int[arr.length];
    sort(arr,0,arr.length-1);  //排序
}
 //分成两段分别排序,然后再合并
private static void sort(int[] A,int p,int r) {
	if(p<r) {   //左指针小于右指针
		int mid=p+((r-p)>>1);  //求中间位置
		sort(A,p,mid);  //对左侧排序
		sort(A,mid+1,r);   //对右侧排序
		merge(A,p,mid,r);   //合并
	}
}
//假设数组的两段分别有序,借助一个辅助数组来缓存原数组,用归并的思路将元素从辅助数组中拷贝原数组
//A原数组        p低位    mid中间位     r高位
private static void merge(int[] A,int p,int mid,int r) {
 //拷贝到辅助空间的相同位置
System.arraycopy(A,p,helper,p,r-p+1);
int left=p,right=mid+1;  //辅助数组的两个指针
//原始数组的 指针
int current=p;  //当前指针指向
while(left<=mid&&right<=r) {  //当左指针走的块已经到头
	if(helper[left]<=helper[right]) {  //辅助空间的左指针小于右指针
		A[current++]=helper[left++];   //当前指针在左指针位置
	}
	else {
		A[current++]=helper[right++];
	}
}
//可能出现左边指针可能没有到头,右边的没有到头可以不管
while(left<=mid) {
	A[current]=helper[left];
	current++;
	left++;
}
}
public static void main(String[] args) {   
	int[] arr=Util.getRandomArr(10,1,100);  //测试指针
	Util.print(arr);
	sart(arr);
	Util.println(arr);
	Assertions.assertThat(Util.checkOrdered(arr,true)).isTrue();
}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值