归并排序的基本思想:采用分治法,先使每个子序列有序,再将有序的子序列进行合并,得到最终的有序序列。
public static void mergeSort(int[] array){
int[] tempArr = new int[array.length]; // 避免递归的创建临时数组
mergeSort(array,tempArr,0,array.length-1);
}
/**
* 对原始数组进行拆分
* @param array 原始数组
* @param tempArr 避免递归的创建临时数组
* @param left 开始索引
* @param right 结束索引
*/
private static void mergeSort(int[] array ,int[] tempArr,int left, int right){
int center = (left+right) / 2;
if(left < right){
mergeSort(array,tempArr,left,center);
mergeSort(array,tempArr,center+1,right);
merge(array,tempArr,left,center+1,right);
}
}
/**
* 对拆分后的数组进行排序并合并
* @param a 原始数组
* @param tempArr 临时数组
* @param leftPos 左边有序序列的开始索引
* @param rightPos 右边有序序列的开始索引
* @param rightEnd 右边有序序列的结束索引
*/
private static void merge(int[] a,int[] tempArr,int leftPos, int rightPos, int rightEnd){
int index = leftPos; //临时数组的索引
int leftEnd = rightPos - 1; //左边数组的结束位置
int nums = rightEnd - leftPos + 1; //总的数组长度
while(leftPos <= leftEnd && rightPos <= rightEnd){
if(a[leftPos] < a[rightPos]){
tempArr[index++] = a[leftPos++];
}else{
tempArr[index++] = a[rightPos++];
}
}
// 如果左边还有元素没有比较完,则全部加入到临时数组中
while(leftPos <= leftEnd){
tempArr[index++] = a[leftPos++];
}
// 如果右边还有元素没有比较完,则全部加入到临时数组中
while(rightPos <= rightEnd){
tempArr[index++] = a[rightPos++];
}
// 将临时数组中的元素全部拷贝到原始数组中
for(int i = 0; i < nums; i++,rightEnd--){
a[rightEnd] = tempArr[rightEnd];
}
}
时间复杂度:O(nlogn)