归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
归并操作(merge),指的是将两个已经排序的序列合并成一个序列的操作。
对两个排序数组合并成一个有序数组,这个很简单
public int[] merge(int[] A,int[] B){ int aLen = A.length; int bLen = B.length; int cLen = aLen + bLen; int[] C = new int[cLen]; int i=0; int j=0; int k=0; while(i<aLen && j<bLen){ if(A[i] <= B[j]){ C[k] = A[i]; k++; i++; }else{ C[k] = B[j]; k++; j++; } } while(i<aLen){ C[k] = A[i]; k++; i++; } while(j<bLen){ C[k] = B[j]; k++; j++; } return C; }
这个时间复杂度O(N+M)
对于一个数组的时候,low - mid是有序的,mid+1--high是有序的,进行归并操作
public void merge(int[] A,int low ,int mid ,int high){ int len = high - low + 1; int[] C = new int[len]; // 只临时保存low - high大小的数组 int i= low; int j = mid + 1; int k = 0; while(i <= mid && j<=high){ if(A[i] <= A[j]){ C[k] = A[i]; k++; i++; }else{ C[k] = A[j]; k++; j++; } } while(i<= mid){ C[k] = A[i]; k++; i++; } while(j<= high){ C[k] = A[j]; k++; j++; } for(i = 0;i<len;i++){ A[i + low] = C[i]; // 更新A } }
归并排序工作原理:(假设序列共有n个元素):
1.将序列每相邻两个数字进行归并操作(merge),形成floor(n/2)个序列,排序后每个序列包含两个元素
2.将上述序列再次归并,形成floor(n/4)个序列,每个序列包含四个元素
3.重复步骤2,直到所有元素排序完毕
public void mergeSort(int[]A,int low,int high){ if(low>=high) return; int mid = low + (high - low)/2; mergeSort(A,low,mid);// 左侧排序 mergeSort(A,mid+1,high); // 右侧排序 merge(A,low,mid,high); // 归并 }
俨然的一种后序遍历的感觉
左侧排序了
右侧排序了
合并了排序数组
空间复杂度:O(N)
时间复杂度:O(NlogN)