思路
首先让数组中的每一个数,视为长度为1的有序区间,
然后把相邻的长度为1的有序区间进行合并,得到最大长度为2的有序区间,
接下来把相邻的长度为2的有序区间进行合并,得到最大长度为4的有序区间,
然后是对相邻的长度为4的有序区间进行合并,依次进行,
直到数组中的所有的数合并成一个统一的区间,排序结束。
归并排序的重点是对两个有序数组进行合并的过程,然后在这个基础上进行递归和分治。
指标
时间复杂度 O(n*logn)
空间复杂度O(n)
代码
public class MergeSort {
public static void mergeSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
mergeSort(arr, 0, arr.length - 1);
}
//一个中点---------------------
public static void mergeSort(int[] arr, int l, int r) {
if (l == r) {//只有一个数了
return;
}
int mid = l + ((r - l) >> 1);//防止溢出;位运算快于除法
mergeSort(arr, l, mid);//左半边,T(N/2)
mergeSort(arr, mid + 1, r);//右半边,T(N/2)
merge(arr, l, mid, r);
}
//两个指针-------------------------
public static void merge(int[] arr, int l, int m, int r) {
int[] help = new int[r - l + 1];//辅助数组
int i = 0;
int p1 = l;
int p2 = m + 1;
while (p1 <= m && p2 <= r) {
help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
}
//两个while只会发生一个。两个只会有一个越界
//负责把剩下的数组拷贝进辅助数组
while (p1 <= m) {
help[i++] = arr[p1++];
}
while (p2 <= r) {
help[i++] = arr[p2++];
}
for (i = 0; i < help.length; i++) {
arr[l + i] = help[i];
}
}
private static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
private static void printArray(int[] arr) {
if (arr == null) {
return;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
int[] arr = new int[] { 3, 5, 4, 2, 6, 7, 1, 9, 8 };
mergeSort(arr);
printArray(arr);
}
}
两个指针p1,p2
网友评论