归并排序:
基本思想:
归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
可以看到这种结构很像一棵完全二叉树,本文的归并排序我们采用递归去实现(也可采用迭代的方式去实现)。分阶段可以理解为就是递归拆分子序列的过程,递归深度为log2^n。
合并相邻有序子序列:
再来看看治阶段,我们需要将两个已经有序的子序列合并成一个有序序列,比如上图中的最后一次合并,要将[4,5,7,8]和[1,2,3,6]两个已经有序的子序列,合并为最终序列[1,2,3,4,5,6,7,8],来看下实现步骤。
代码实现:
public class MergeSort { public static void main(String[] args) { int[] a = new int[]{49, 38, 65, 97, 76, 13, 27}; int len = a.length; MergeSort(a,0,len-1); } static int[] b = new int[7]; static void Merge(int a[], int low, int mid, int high){ int k,i,j; for (k = low; k <= high; k++) { //将所有元素复制到b中 b[k] = a[k]; } for (i = low,j=mid+1,k=i;i<=mid&&j<=high;k++){ //比较b中的左右两段中的元素 if(b[i]<=b[j]){ //将较小的值复制到a中 a[k]=b[i++]; }else { a[k]=b[j++]; } } //若第一个表未检测完,复制 while (i<=mid) a[k++]=b[i++]; //若第二个表未检测完,复制 while (j<=high) a[k++]=b[j++]; } static void MergeSort(int a[], int low, int high){ if(low<high){ //从中间划分两个子序列 int mid=(low+high)/2; //对左侧子序列进行递归排序 MergeSort(a,low,mid); //对右侧子序列进行递归排序 MergeSort(a,mid+1,high); //归并 Merge(a,low,mid,high); //输出每次归并排序 //如果你对每次的排序输出不知道,仔细分析如何递归,代码先后 //根据代码逻辑知,先输出左边的每次归并排序,在输出右边每次归并排序,最终进行最后一次归并排序 for (int c=0;c<a.length;c++) { System.out.print(a[c]+" "); } System.out.println(); } } }
每次归并结果:
输出每次归并排序
如果你对每次的排序输出不知道,仔细分析如何递归,代码先后:
先输出左侧子序列的归并排序
在输出右侧子序列的归并排序
最后输出总排序
根据代码逻辑知,先输出左边的每次归并排序,在输出右边每次归并排序,最终进行最后一次归并排序