算法原理
归并排序(Merge Sort)是建立再归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列间有序。将两个有序表合并成一个有序表,称为2-路归并。
算法描述
- 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列。
- 设定两个指针,最初位置分别为两个已排序序列的起始位置。
- 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置。
- 重复步骤3直到某一指针到达序列尾。
- 将另一序列剩下的所有元素直接复制到合并序列尾。
动图展示
注:动图来源于菜鸟教程
算法实现
/**
* 归并排序
*/
public class MergeSort {
public static void main(String[] args) {
int[] arr = {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};
arr = mergeSort(arr);
printArray(arr);
}
public static void printArray(int[] arr){
for(int a : arr)
System.out.print(a+",");
System.out.println();
}
public static int[] mergeSort(int[] arr){
if(arr.length < 2){
return arr;
}
int middle = (int) Math.floor(arr.length/2);
int[] left = Arrays.copyOfRange(arr,0,middle);
int[] right = Arrays.copyOfRange(arr,middle,arr.length);
return mergeSort(mergeSort(left),mergeSort(right),arr.length);
}
public static int[] mergeSort(int[] left, int[] right, int length){
int[] result = new int[length];
int i =0;
while(left.length > 0 && right.length > 0){ // 左右两组都有数据时
if(left[0] <= right[0]){
result[i] = left[0]; // 目标数组添加第一项
int[] temp = new int[left.length-1];
System.arraycopy(left,1,temp,0,temp.length); // 移除数组第一项
left = temp;
}else {
result[i] = right[0]; // 目标数组添加第一项
int[] temp = new int[right.length-1];
System.arraycopy(right, 1, temp, 0, temp.length); // 移除数组第一项
right = temp;
}
i++;
}
while (left.length > 0){ // 右边数组无数据时
result[i] = left[0]; // 目标数组添加第一项
int[] temp = new int[left.length-1];
System.arraycopy(left,1,temp,0,temp.length); // 移除数组第一项
left = temp;
i++;
}
while (right.length > 0){ // 左边数组无数据时
result[i] = right[0]; // 目标数组添加第一项
int[] temp = new int[right.length-1];
System.arraycopy(right, 1, temp, 0, temp.length); // 移除数组第一项
right = temp;
i++;
}
return result;
}
}