归并排序(Merge-Sort)
归并排序属于外部排序
基础部分
归并排序的算法思想:
左边处理一下(对左半边排序)
右边处理一下(对右半边排序)
最后处理左右两边的(两边一起处理)
代码实现
class MargeSort {
public static void margeSort(int[] nums){
margeSort(nums,0,nums.length - 1);
}
public static void margeSort(int[] nums,int l,int r){
if(l >= r) return;
int mid = (r + l) >> 1;
margeSort(nums,l,mid);
margeSort(nums,mid + 1,r);
int[] numCopy = new int[r - l + 1];
int k = 0;//numCopy的起始下标
int i = l;//左数组的起始下标
int j = mid + 1;//有数组的起始下标
while(i <= mid || j <= r){
if(j > r || (i <= mid && nums[i] < nums[j])){
numCopy[k++] = nums[i++];
}else{
numCopy[k++] = nums[j++];
}
}
for(int ind = l;ind <= r;ind++)
nums[ind] = numCopy[ind - l];
}
}
测试:
public class Main{
public static void main(String args[]){
int[] nums = new int[]{
9,8,7,6,5,44,1,3,445,23};
System.out.println(Arrays.toString(nums));
MargeSort.margeSort(nums);
System.out.println(Arrays.toString(nums));
}
}
[9, 8, 7, 6, 5, 44, 1, 3, 445, 23]
这里是已排序数组:[8, 9]
这里是已排序数组:[7, 8, 9]
这里是已排序数组:[5, 6]
这里是已排序数组:[5, 6, 7, 8, 9]
这里是已排序数组:[1, 44]
这里是已排序数组:[1, 3, 44]
这里是已排序数组:[23, 445]
这里是已排序数组:[1, 3, 23, 44, 445]
这里是已排序数组:[1, 3, 5, 6, 7, 8, 9, 23, 44, 445]
[1, 3, 5, 6, 7, 8, 9, 23, 44, 445]
归并排序在大数据场景下的应用
问题:电脑内存大小2GB,如何对一个40GB的文件进行排序
答:把40GB大文件分成20分2GB的小文件,然后借助外部存储区进行20路归并排序
经典面试题
归并排序基础
LeetCode剑指 Offer 51. 数组中的逆序对
class Solution {
int[] temp;
public int reversePairs(int[] nums) {
temp = new int[nums.length];
return margeSort(nums,0,nums.length - 1);
}
public int margeSort(int[] nums,int l,int r){
if(l >= r) return 0;
int ans = 0;
int mid = (l + r) >> 1;
ans += margeSort(nums,l,mid);
ans += margeSort(nums,mid + 1,r);
int k = l;
int p1 = l