归并排序时间复杂度:最好最坏平均都是nlogn
空间复杂度:n
稳定性:稳定的
归并排序的用途:
1、排序
(速度仅次于 快速排序,但较稳定)2、求逆序对数【这个单独出个笔试题,求逆序对数】
具体思路是,在归并的过程中计算每个小区间的逆序对数,进而计算出大区间的逆序对数(也可以用树状数组来求解)
JAVA实现归并排序:
import java.util.Arrays;
public class MergeSort {
public static void main(String args[]){
int a[] = {4,4,1,6,3};
mergeSort(a,0,a.length-1);
/*for(int i=0;i<a.length-1;i++)
System.out.println(a[i]);
*/
System.out.println(Arrays.toString(a));
}
private static void mergeSort(int a[],int start,int end){
//int mid = (start+end)/2;
//int[] temp = new int[a.length];
int mid=(start&end)+((start^end)>>1);
if(start<end){//跳出递归,原来忘记写这一句,导致栈溢出
mergeSort(a,start,mid);
mergeSort(a,mid+1,end);
merge(a,start,mid,mid+1,end);
}
}
private static void merge(int a[],int start1,int end1,int start2,int end2){
int i = start1;
int j = start2;
//int k = 0;//k与此处保持一致,System.arraycopy(temp, 0, a, start1, end2-start1+1);
int k = start1;//k与此处保持一致,System.arraycopy(temp, start1, a, start1, end2-start1+1);
int temp[] = new int[a.length+1];
while(i<=end1 && j<=end2){
if(a[i] < a[j]){
temp[k++] = a[i++];
//temp[k] = a[i];
//i++;
}
else{
temp[k++] = a[j++];
//temp[k] = a[j];
//j++;
}
//k++;
}
while(i<=end1){
temp[k++] = a[i++];
}
while(j<=end2){
temp[k++] = a[j++];
}
//k = start1;
//for(int element:temp){//把临时数组元素赋值给原数组
//a[k++] = element;
System.arraycopy(temp, start1, a, start1, end2-start1+1);
}
}
删除注释后的完整可运行代码:
import java.util.Arrays;
public class MergeSort {
public static void main(String args[]){
int a[] = {4,4,1,6,3};
mergeSort(a,0,a.length-1);
/*for(int i=0;i<a.length-1;i++)
System.out.println(a[i]);
*/
System.out.println(Arrays.toString(a));
}
private static void mergeSort(int a[],int start,int end){
//int mid = (start+end)/2;
int mid=(start&end)+((start^end)>>1);
if(start<end){//跳出递归,原来忘记写这一句,导致栈溢出
mergeSort(a,start,mid);
mergeSort(a,mid+1,end);
merge(a,start,mid,mid+1,end);
}
}
private static void merge(int a[],int start1,int end1,int start2,int end2){
int i = start1;
int j = start2;
int k = start1;//k与此处保持一致,System.arraycopy(temp, start1, a, start1, end2-start1+1);
int temp[] = new int[a.length+1];
while(i<=end1 && j<=end2){
if(a[i] < a[j]){
temp[k++] = a[i++];
}
else{
temp[k++] = a[j++];
}
}
while(i<=end1){
temp[k++] = a[i++];
}
while(j<=end2){
temp[k++] = a[j++];
}
System.arraycopy(temp, start1, a, start1, end2-start1+1);//从temp数组复制到a数组
}
}