归并排序
主要思想是分治
- 每次取中间点
mid = l + r >> 1
- 递归排序从
0到mid
和mid + 1到r
- 归并操作的时候首先用两个指针分别指向左右两个数组中的最小值
- 比较谁更小,更小的放在答案数组的第一位
- 放入的指针往后走,在继续比较
- 直至某数组到头,另一数组的剩余部分直接接入答案数组
时间复杂度: O(nlogn)
import java.util.Scanner;
public class MergeSort {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i ++ ) arr[i] = sc.nextInt();
merge_sort(arr, 0, n - 1);
for (int i = 0; i < n; i ++ ) System.out.print(arr[i] + " ");
}
static void merge_sort(int[] arr, int l, int r) {
if (l >= r) return;//递归的终止情况
int mid = l + r >> 1;//第一步:分成子问题
//递归处理子问题
merge_sort(arr, l, mid);
merge_sort(arr, mid + 1, r);
int k = 0, i = l, j = mid + 1;
int[] tmp = new int[r - l + 1];
//比较左右两个数组的各个值谁更小
while (i <= mid && j <= r) {
if (arr[i] <= arr[j]) tmp[k ++ ] = arr[i ++ ];
else tmp[k ++ ] = arr[j ++ ];
}
//如果左数组或右数组有剩余部分,则直接接入答案数组
while (i <= mid) tmp[k ++ ] = arr[i ++ ];
while (j <= r) tmp[k ++ ] = arr[j ++ ];
//将答案数组赋值给原数组
for (i = l, j = 0; i <= r; i ++, j ++ ) {
arr[i] = tmp[j];
}
}
}