归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
一、归并排序的思想
【1】如下图,可以看到这种结构很像一棵完全二叉树,本文的归并排序我们采用递归去实现(也可采用迭代的方式去实现)。分阶段可以理解为就是递归拆分子序列的过程。
【2】归并排序思想示意图2(合并相邻有序子序列):再来看看治阶段,我们需要将两个已经有序的子序列合并成一个有序序列,比如上图中的最后一次合并,要将[4,5,7,8]和[1,2,3,6]两个已经有序的子序列,合并为最终序列[1,2,3,4,5,6,7,8],来看下实现步骤:会使用到一个临时内存变量temp;
二、归并排序案例
归并排序的应用案例:给你一个数组,val arr = Array(5,4,6,3,7,2,8,9,1,0,8,3), 请使用归并排序完成排序。
package com.algorithms;
import java.util.Arrays;
/**
* 归并排序
*/
public class MergeSort {
public static void main(String[] args) {
int arr[] = new int[]{5,4,6,3,7,2,8,9,1,0,8,3};
MergeSort mergeSort = new MergeSort();
mergeSort.mergeSort(arr,0,arr.length-1,new int[arr.length]);
System.out.printf(Arrays.toString(arr));
}
//分解数据 + 合并数据
public 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);
}
}
/*
* 合并方法思想:【1】、将left——mid 之间的数据 与 mid+1——right 之间的数据进行比较,并顺序的放到 temp 中;
* 【2】上述结束后,情况一:右边的数据遍历结束,但是左边的数据还有时,将左边的全部数据复制到temp中;
* 情况二:左边的数据遍历结束,但是右边的数据还有时,将右边的全部数据复制到temp中;
*/
public void merge(int[] arr,int left,int mid,int right,int[] temp){
//temp的下标
int t = 0;
//left 的值后续要用这里暂存起来
int l = left;
//因为右边的元素对mid进行了操作,所以这里需要获取传入的mid并锁死
int m = mid;
while(left <= m && mid+1 <= right){
if(arr[left] < arr[mid+1]){
temp[t] = arr[left];
t++;
left++;
}else{
temp[t] = arr[mid+1];
t++;
mid++;
}
}
//情况一
while(left <= m){
temp[t] = arr[left];
t++;
left++;
}
//情况二
while(mid+1 <= right){
temp[t] = arr[mid+1];
mid++;
t++;
}
//将temp的值复制到arr中
//先将temp的下标还原
t=0;
while(l <= right){
arr[l] = temp[t];
t++;
l++;
}
}
}
----关注公众号,获取更多内容----