归并排序(合并排序)
平均切分待排序区间,如果待排序区间的左右两个小区间已经有序,则按照合并有序数组的方式,使最终区间有序。
- 找中间位置,划分左右两个小区间,直到小区间长度 = =1或 < 1
- 分治思想,先排序左右两个小区间
- 合并有序数组
//归并排序
//[ , )
public static void mergeSort(int[] array){
mergeSortInternal(array,0,array.length);
}
public static void mergeSortInternal(int[] array,int low,int high){
if(low+1>=high){
return ;
}
int mid=(low+high)/2;
//[low,mid)
//[mid,high)
mergeSortInternal(array,low,mid);
mergeSortInternal(array,mid,high);
merge(array,low,mid,high);
}
合并两个有序数组
//[low,mid)- - 左区间
//[mid,high)- - 右区间
- 左区间,右区间同时遍历比较,小的数放到新的数组
- 左区间无数据,右区间未遍历完,把右区间的数直接补到新数组后
左区间有数据,右区间无数据,亦如此
//合并有序数组
private static void merge(int[] array,int low,int mid,int high){
int length=high-low;
int[] extra=new int[length];
//[low,mid)
//[mid,high)
int iLeft=low;
int iRight=mid;
int iExtra=0;
while(iLeft<mid&&iRight<high){
if(array[iLeft]<=array[iRight]){
extra[iExtra++]=array[iLeft++];
}else{
extra[iExtra++]=array[iRight++];
}
}
while(iLeft<mid){
extra[iExtra++]=array[iLeft++];
}
while(iRight<high){
extra[iExtra++]=array[iRight++];
}
for(int i=0;i<length;i++){
array[low+i]=extra[i];
}
}