归并排序涉及到三个阶段:
一、递归分割阶段
二、迭代合并阶段
三、数组复制归位
有两个方法配合完成sort和msort,sort方法中把自己的需要排序的参数数组复制了一个新数组
下面分解迭代合并的步骤:
下面的序列有11个元素,索引范围为[first,last),mid=(first+last)/2=(0+11)/2=5
package test;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Random;
public class mergeSort {
public static void main(String[] args) {
int[] arrA= {25,10,7,19,3,48,12,17,56,30,21};
int[] arrB= {7,10,19,25,12,17,21,30,48};
System.out.println("排序前的数组:"+Arrays.toString(arrA));
sort(arrA);
System.out.println("排序后的数组:"+Arrays.toString(arrA));
System.out.println("排序前的数组:"+Arrays.toString(arrB));
sort(arrB);
System.out.println("排序后的数组:"+Arrays.toString(arrB));
int[] arrC= new int[25];
Random rnd = new Random();
for (int i = 0; i < 25; i++) {
arrC[i]=rnd.nextInt(9000);
}
System.out.println("排序前的数组:"+Arrays.toString(arrC));
sort(arrC);
System.out.println("排序后的数组:"+Arrays.toString(arrC));
}
public static void sort(int arr[]) {
int tmpArr[]=arr.clone();
msort(arr,tmpArr,0,arr.length);
}
private static void msort(int[] arr, int[] tmpArr, int first, int last) {
//递归终止的条件是,子列表都成为单元素子列表 first+1==last
if(first+1<last) {
/递归分割阶段//
int mid=(first+last)/2;
msort(arr,tmpArr,first,mid);//递归子列表A [first,mid)
msort(arr,tmpArr,mid,last);//递归子列表B [mid,last)
//是否进行递归合并子列表的判断条件.合并列表终止的条件
if(arr[mid-1]<arr[mid]) {
return;
}
/迭代合并阶段///
int indexA,indexB,indexC;
indexA=indexC=first;
indexB=mid;
//扫描上子列表a,indexA作为指针;扫描下子列表b,indexB作为指针
while(indexA<mid && indexB<last) {
//比较当前指针的元素arr[indexA],arr[indexB]谁小谁进tmpArr[indexC]
if(arr[indexA]<arr[indexB]) {
tmpArr[indexC]=arr[indexA];
indexA++;
}else {
tmpArr[indexC]=arr[indexB];
indexB++;
}
indexC++;
}
//如果合并完成之后子列表A有剩余元素,直接拼接到tmpArr后面
while(indexA<mid) {
tmpArr[indexC]=arr[indexA];
indexA++;
indexC++;
}
//如果合并完成之后子列表B有剩余元素,直接拼接到tmpArr后面
while(indexB<last) {
tmpArr[indexC]=arr[indexB];
indexC++;
indexB++;
}
//克隆阶段/
//所有元素都从arr---> tmpArr之后,再来一次克隆回arr操作
for(int i=first;i<last;i++) {
arr[i]=tmpArr[i];
}
}
}
}
运行结果: