归并的思想其实不难,就是假设有两个有序数组a,b,现在需要把它合并成一个有序的数组,要是使用快排或者其他的排序(除了桶排序)理论值就达到了O(N*logN)了,假如我建立一个数组c,长度是他们两个数组的和,然后从两个数组a,b他们的第一个值来比较,将小的放到c的前面,然后指针下移一个位置,再拿出两个数组前面的较小值放到c,,,这样就使用了O(N)的时间复杂度完成了排序。
剩下的就是递归的问题了,这个也不好讲,直接看代码。
import java.util.Arrays;
public class MergeSort2 {
//归并排序
public static void mergeSort(int a[]){
int[]b = new int[a.length];
process(a, b, 0, a.length-1);
}
//递归过程
public static void process(int a[],int b[], int left,int right){
if(left>=right){
return ;
}
int mid = (left+right)/2;
//先进行递归
process(a,b, left, mid);
process(a,b, mid+1, right);
//再进行归并
merge(a, b, left, right, mid);
arrayCopy(a, b, left,right);
}
//归并过程
public static void merge(int a[],int b[],int left,int right,int mid){
int k = left;//b数组的起始
int i = left;
int j = mid+1;
while(i<=mid && j<=right){//此处精简代码!!
b[k++] = a[i]>a[j]?a[j++]:a[i++];
}
while(i<=mid){
b[k++] = a[i++];
}
while(j<=right){
b[k++] = a[j++];
}
}
//复制数组
public static void arrayCopy(int[]a,int[]b,int left,int right){
for (int i = left; i <= right; i++) {
a[i] = b[i];
}
}
for test(对数器)/
//复制数组
public static int[] arrayCopy(int []a){
int[]b = new int[a.length];
for (int i = 0; i < b.length; i++) {
b[i] = a[i];
}
return b;
}
//获取一个数组
public static int[] getArray(int len,int val){
int arr[] = new int[len];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int)(Math.random()*val)-(int)(Math.random()*val);
}
return arr;
}
//打印一维数组
public static void printArray(int arr[]){
for (int i : arr) {
System.out.print(i+" ");
}
System.out.println();
}
//判断两个数组是否相等
public static boolean isEqual(int arr1[],int arr2[]){
if(arr1==null||arr2==null||arr1.length!=arr2.length){
return false;
}
for (int i = 0; i < arr2.length; i++) {
if(arr1[i]!=arr2[i]){
return false;
}
}
return true;
}
//test
public static void main(String[] args) {
int len = 10;
int val = 100;
int times = 100000;
boolean isOK = true;
while(times-->0){
int arr1[] = getArray(len, val);
int arr2[] = arrayCopy(arr1);
mergeSort(arr1);
Arrays.sort(arr2);
isOK = isEqual(arr1, arr2);
if(!isOK){//如果出错,就输出
System.out.println("第几次:"+times);
printArray(arr1);
printArray(arr2);
break;
}
}
System.out.println(isOK);
}
}