归并排序
基本介绍
归并排序是利用 归并的思想实现的排序方法
该算法采用经典的分治策略(分治法将问题分成一些小的问题然后递归求解,而治的阶段则将分的阶段得到的个答案“修补”在一起,即分而治之)
分析
再来看看治阶段,我们需要将两个已经有序的子序列合并成一个有序序列,比如上图中的最后一次合并,要将[4,5,7,8]和[1,2,3,6]两个已经有序的子序列,合并为最终序列[1,2,3,4,5,6,7,8],来看下实现步骤:
代码实现
package F排序;
import java.util.Arrays;
/**
* @Author Zhou jian
* @Date 2020 ${month} 2020/1/4 0004 16:54
* 归并排序
*/
public class MergeSort {
public static void main(String[] args) {
int[] arr ={8,4,5,7,1,3,6,2};
int[] temp = new int[8]; //归并排序需要额外的空间
mergeSort(arr,0,arr.length-1,temp);
System.out.println("归并排序后结果为"+ Arrays.toString(arr));
}
//合并的方法
/**
*
* @param arr 需要排序的原始数组
* @param left 左边有序序列初始索引
* @param mid 中间索引
* @param right 右边索引
* @param temp 做中专的数组
*/
public static void merge(int[] arr,int left,int mid,int right,int[] temp){
int i = left; //初始化i,左边有序序列的初始索引
int j = mid+1;//初始化j,右边有序序列的初始索引
int t = 0;//临时数组的当前索引
//1、先把左右两边(有序)的数据按照规则填充到temp中,直到左右两边的有序数列有一边处理完毕
while(i<=mid && j<=right){
//如果左边的有序序列的当前元素,小于等于右边有序序列的当前元素
//即将左边的当前元素拷贝到temp数组的t位置
//然后t++ i++ 移动
if(arr[i]<=arr[j]){
temp[t] = arr[i];
t +=1;
i +=1;
}else{//反之,左边的有序序列大于右边的有序序列,则将右边有序序列的数据填充到临时数组
temp[t] = arr[j];
t +=1;
j +=1;
}
}
//2、总有一边有剩余,把有剩余数据的一边的数据依次全部填充到temp
while(i<=mid){//左边的有序序列有剩余的锇元素,全部填充到temp
temp[t] = arr[i];
t++;
i++;
}
while(j<=right){//右边的有序序列还有剩余,就全部填充到temp
temp[t] = arr[j];
t++;
j++;
}
//3、将temp数组的元素拷贝到arr
//注意并不是每次都拷贝所有
t =0;
int tempLeft = left;
//第一次合并时 tempLeft = 0,right=1 ;
// 第二次合并 tempLeft=2 right=3
// 第三次 tempLeft=0 right=3
//最后一次合并 tempLeft = 0 right=7
while(tempLeft<=right){//
arr[tempLeft]=temp[t];
t++;
tempLeft++;
}
}
//分+和的方法
public static void mergeSort(int[] arr,int left,int right,int[] temp){
if(left<right){
int mid = (left+right)/2; //中间的索引
//向左递归进行分解
mergeSort(arr,left,mid,temp);
//向右递归
mergeSort(arr,mid+1,right,temp);
//合并
merge(arr,left,mid,right,temp);
}
}
}
性能分析‘
排序前的时间是2020-01-04 18:06:50
排序后的时间是2020-01-04 18:06:50