归并排序,采用了递归的思想,先将左半部分排好序,再将右半部分排好序,最后将两个排序好的数组进行外排序。
时间复杂度为O(N*logN)
递归排序的代码如下:
public class MergeSort {
public static void mergeSort(int[] arr){
if(arr == null || arr.length < 2) return;
mergeSort(arr,0,arr.length-1);
}
public static void mergeSort(int[] arr,int left,int right){
if(left == right) return;
int mid = left + (right-left)/2;
mergeSort(arr,left,mid);
mergeSort(arr,mid+1,right);
merge(arr,left,mid,right);
}
public static void merge(int[] arr,int left,int mid,int right){
int[] help = new int[right-left+1];
int i = 0;
int p1 = left;
int p2 = mid+1;
while (p1<=mid && p2<=right){
help[i++] = arr[p1]<arr[p2] ? arr[p1++]:arr[p2++];
}
while (p1<=mid) help[i++] = arr[p1++];
while (p2<=right) help[i++] = arr[p2++];
for(int j=0;j<help.length;j++){
arr[left+j] = help[j];
}
}
public static void printArray(int[] arr){
for(int i=0;i<arr.length;i++){
System.out.print(arr[i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
int[] arr = {10,2,50,30,25,15,4,7,6,15};
mergeSort(arr);
printArray(arr);
}
}
在求mid的时候采用 L+(R-L)/2 比较安全,可以保证不会产生溢出,使用位运算 L+(R-L)>>1 可以让计算变得快一点,因为位运算比算术运算比较快
扩展:可以用归并排序的思想解决小和问题与逆序对问题。
求最小和的代码如下
public class MergeSort {
public static int mergeSort(int[] arr){
if(arr == null || arr.length < 2) return 0;
//返回最小和
return mergeSort(arr,0,arr.length-1);
}
public static int mergeSort(int[] arr,int left,int right){
if(left == right) return 0;
int mid = left + (right-left)/2;
//左边的最小和加上右边的最小和再加上将左边跟右边进行排序之后得到的最小和
return mergeSort(arr,left,mid)+mergeSort(arr,mid+1,right)+merge(arr,left,mid,right);
}
public static int merge(int[] arr,int left,int mid,int right){
int[] help = new int[right-left+1];
int i = 0;
int p1 = left;
int p2 = mid+1;
int sum = 0;
while (p1<=mid && p2<=right){
sum += sum += arr[p1] < arr[p2]?(right - p2 + 1)*arr[p1]:0;
help[i++] = arr[p1]<arr[p2] ? arr[p1++]:arr[p2++];
}
while (p1<=mid) help[i++] = arr[p1++];
while (p2<=right) help[i++] = arr[p2++];
for(int j=0;j<help.length;j++){
arr[left+j] = help[j];
}
return sum;
}
public static void printArray(int[] arr){
for(int i=0;i<arr.length;i++){
System.out.print(arr[i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
int[] arr = {10,2,50,30,25,15,4,7,6,15};
System.out.println(mergeSort(arr));
printArray(arr);
}
}