1.图文讲解
「归并排序」是分治思想的典型应用,它包含这样三个步骤:
①分解: 待排序的区间为 [l, r],令 mid = (l+r)/2。把区间[l,r]分成[l,m] 和 [m+1,r]
②解决: 使用归并排序递归地排序两个子序列
③合并: 把两个已经排好序的子序列 [l, m][l,m] 和 [m + 1, r][m+1,r] 合并起来
在待排序序列长度为 1的时候,递归开始「回升」,因为我们默认长度为 1 的序列是排好序的。
① https://blog.csdn.net/jianyuerensheng/article/details/51262984
② https://blog.csdn.net/MoreWindows/article/details/6678165
2.视频讲解
3.java代码
package com.algorithm.learn.sort08;
import java.text.CharacterIterator;
import java.util.Arrays;
/**
* @program: soword-finger-offer-learn
* @description:
* @author: long
* @create: 2020-06-19 11:16
**/
public class MergeSort {
public static void merge(int[] arr, int left, int mid, int right){
//创建临时数组tmp,及其指针k
int[] tmp = new int[right-left+1];
int k = 0;
//左右指针
int i = left, j = mid+1;
//先把小数移动到临时数组 {8,7,9,5,10,1}
while(i <= mid && j <= right){
if(arr[i] < arr[j]){
tmp[k++] = arr[i++];
//k++;
//i++;
}else{
tmp[k++] = arr[j++];
}
}
//左边剩余的数移动到数组
while(i <= mid){
tmp[k++] = arr[i++];
}
//右边剩余的数移动到数组
while(j <= right){
tmp[k++] = arr[j++];
}
//新数组 覆盖原数组
for (int l = 0; l < tmp.length; l++) {
arr[l+left] = tmp[l];
}
}
// {8,7,9,5,10,1}
public static void mergerSort(int[] arr, int left, int right){
int mid = (left + right) /2;
if(left < right){
//左边
mergerSort(arr,left,mid);
//右边
mergerSort(arr,mid+1,right);
//左右归并
merge(arr,left,mid,right);
System.out.println(Arrays.toString(arr));
}
}
public static void main(String[] args) {
int arr[] = {8,7,9,5,10,1};
mergerSort(arr,0,arr.length-1);
System.out.println("排序结果:" + Arrays.toString(arr));
}
}
4.归并经典例题
① 数组中的逆序对