归并排序
* 数组分为左右两个子数组,按序依次比较子数组中每个元素大小,将小的元素放入新的临时数组中。
时间复杂度O(nlog2n);
空间复杂度O(n);
稳定
public static void main(String[] args) {
int[] array = {9, 6, 11, 3, 5, 12, 8, 7, 10, 15, 14, 4, 1, 13, 2};
System.out.println("=======归并排序=======");
sort(array);
for (int i : array) {
System.out.print(i + " ");
}
}
public static void sort(int[] arr) {
//在排序前,先建好一个长度等于原数组长度的临时数组,避免递归中频繁开辟空间
int[] temp = new int[arr.length];
sort(arr, 0, arr.length - 1, temp);
}
/**
* 递归调用完成归并排序
* 四个参数:
* 需要排序的数组
* 左指针所指index
* 右指针所指index
* 临时数组
*/
static void sort(int[] arr, int left, int right, int[] temp) {
if (left < right) {
int mid = (left + right) / 2;
//左边归并排序,使得左子序列有序
sort(arr, left, mid, temp);
//右边归并排序,使得右子序列有序
sort(arr, mid + 1, right, temp);
//将两个有序子数组合并操作
merge(arr, left, mid, right, temp);
}
}
/**
* 五个参数:
* 需要排序的数组
* 左侧子数组的开始位置
* 右侧子数组的开始位置
* 需要排序的数组结束位置
* 临时数组
*/
static void merge(int[] arr, int left, int mid, int right, int[] temp) {
//左序列指针
int i = left;
//右序列指针
int j = mid + 1;
//临时数组指针
int t = 0;
while (i <= mid && j <= right) {
temp[t++] = arr[i] <= arr[j] ? arr[i++] : arr[j++];
}
//将左边剩余元素填充进temp中
while (i <= mid) {
temp[t++] = arr[i++];
}
//将右序列剩余元素填充进temp中
while (j <= right) {
temp[t++] = arr[j++];
}
t = 0;
//将temp中的元素全部拷贝到原数组中
while (left <= right) {
arr[left++] = temp[t++];
}
}