归并排序参考图

package com.test.sort;
import java.util.Arrays;
/**
* 归并排序基本思想:
* 归并排序分为两个阶段:
* 第一阶段分:将待排序序列分为两个序列,再分别对两个序列再次分裂,直至分为一个最小单元,此时不可再分
* 第二阶段治:将上面已经分割好的最小单元序列合并为一个有序序列,依次向上合并
* 最终达到整个序列的排序目的
*/
public class MergeSortDemo {
public static void main(String[] args) {
int[] arr=new int[]{6,7,8,5,9,3,2,4};
divide(0,arr.length-1,arr);
System.out.println(Arrays.toString(arr));
}
/**
*
* @param left 待分割后的序列第一个元素下标
* @param right 待分割后的序列最后一个元素下标
* @param arr 原始数组
*/
public static void divide(int left,int right,int[] arr){
int middle=(left+right)/2;
if(left<right){
//左递归分割,分割完成的为{6,7}
divide(left,middle,arr);
//右递归分割,分割完成的为{2,4}
divide(middle+1,right,arr);
//对分割后的序列进行排序
rule(left,right,arr);
}
}
/**
* 合并两个有序序列
* @param left 分割后的序列第一个元素下标
* @param right 分割后的序列最后一个元素下标
* @param arr 原始数组
*/
public static void rule(int left,int right,int[] arr){
//左序列起始下标
int i=left;
//左序列最后一个元素下标
int middle=(left+right)/2;
//右序列起始下标
int j=middle+1;
//临时数组下标
int temp=0;
//临时数组
int[] tempArr=new int[arr.length];
while(j<=right && i<=middle){
if(arr[i]>arr[j]){
// leftArr={6,7} rightArr={5,8} 第一次合并后得到有序序列
//如果左序列leftArr[0]>右序列rightArr[0](arr[middle+1]),把rightArr[0]放入临时数组,把rightArr的下一个元素再与leftArr[0]比较
//如果左序列leftArr[0]<右序列rightArr[0](arr[middle+1]),把leftArr[0]放入临时数组,把leftArr的下一个元素再与rightArr[0]比较
//例上面的序列,第一步 6>5,把5放入临时数组。第二步 6<8,把6放入临时数组,第三步 7<8,把7放入临时数组
tempArr[temp]=arr[j];
temp++;
j++;
}else{
tempArr[temp]=arr[i];
temp++;
i++;
}
}
//如果经过比较 右边序列全部放入临时数组,此时左边序列有剩余,把剩余的全部放入临时数组
while (i<=middle){
tempArr[temp++]=arr[i++];
}
while (j<=right){
tempArr[temp++]=arr[j++];
}
//把临时数组有序的元素复制到原始数组中的对应位置
// temp表示此时合并时有多少个元素
for (int k=0;k<temp;k++){
arr[left++]=tempArr[k];
}
}
}