[置顶] 递归与分治策略-2.7归并排序及其优化总结
2017-10-07 23:02
295 查看
引言:众所周知,归并排序(合并排序)算法是基于分治策略的一个排序算法,其基本思想是:将待排序元素分成大小大致相同的2个子集合,分别对2个子集合进行排序,最终将排序好的子集合合并成为所要求的排好序的集合。具体过程如下图所示(动图源于网络):
如图所示:归并排序需要三个索引分别是
递归代码如下:
运行结果如下:
读者可以发现在mergeSort递归算法里面,每一次都要进入merge方法进行合并,可事实并不是每一次都需要。比如归并的两部分数组拼接到一起就已经是成序的数组或者输入的数组就已经是有序的数组,这样就不需要再进一步合并。因此可以在此前加一个判断即可减少一定的归并次数。
优化代码如下:
以上通过判断第一部分数组的最后一个元素是否小于另一部分数组第一个元素来实现,即加上
补充:以上只讨论了归并排序的递归实现,是自顶向下的,实际上还有迭代法的实现,即自底向上。迭代法程序比递归法略长,但特点是可无需向数组中通过索引读取元素,这使得迭代法可用在数据结构是链表的情况下进行排序。
如图所示:归并排序需要三个索引分别是
i,
j,
k。其中
i指向带排序第一个子集合待比较元素,
j指向待排序另一个子集合待比较元素,
k指向数组b中的元素。
递归代码如下:
public static void mergeSort(int a[],int l,int r){ if(l>=r) return; //递归尾->至少有两个元素 int m = (l+r)/2; 4000 mergeSort(a,l,m); //类似细胞分解,左半 mergeSort(a,m+1,r); //类似细胞分解,有半 merge(a,b,l,m,r); //将a数组排好序合并到b数组里,最后复制回a }
public static void merge(int a[],int b[],int l,int m,int r){ //1.开始归并 int i=l,k=l,j=m+1; while(i<=m&&j<=r){ if(a[i]<=a[j]){ //这是归并排序是稳定性排序的关键条件,若取严格不等号,则不稳定 b[k++] = a[i++]; }else b[k++] = a[j++]; } //2.对结尾元素进行处理 if(i<=m){ for(int q=i;q<=m;q++) b[k++] = a[q]; }else{ for(int q=j;q<=r;q++) b[k++] = a[q]; } //3.复制回数组a for(int q=l;q<=r;q++) a[q] = b[q]; }
运行结果如下:
初始数组:49 38 65 97 76 13 27 排序数组:13 27 38 49 65 76 97
读者可以发现在mergeSort递归算法里面,每一次都要进入merge方法进行合并,可事实并不是每一次都需要。比如归并的两部分数组拼接到一起就已经是成序的数组或者输入的数组就已经是有序的数组,这样就不需要再进一步合并。因此可以在此前加一个判断即可减少一定的归并次数。
优化代码如下:
public static void mergeSort(int a[],int l,int r){ if(l>=r) return; //递归尾->至少有两个元素 int m = (l+r)/2; mergeSort(a,l,m); //类似细胞分解,左半 mergeSort(a,m+1,r); //类似细胞分解,有半 if(a[m]>a[m+1]) merge(a,b,l,m,r); //将a数组排好序合并到b数组里 }
以上通过判断第一部分数组的最后一个元素是否小于另一部分数组第一个元素来实现,即加上
if(a[m]>a[m+1])判断。因为两部分数组已经各自成序,只要判断其边缘元素大小即可。
补充:以上只讨论了归并排序的递归实现,是自顶向下的,实际上还有迭代法的实现,即自底向上。迭代法程序比递归法略长,但特点是可无需向数组中通过索引读取元素,这使得迭代法可用在数据结构是链表的情况下进行排序。
相关文章推荐
- [置顶] 快速排序及其优化过程总结
- [置顶] 递归与分治策略-2.9.2线性时间选择(取中位数的中位数基准)(第k小问题)
- 递归和分治策略的算法总结
- 常见性能优化策略的总结
- zxing扫描二维码和识别图片二维码及其优化策略
- 递归与分治策略
- 递归与分治策略之快速排序
- 深度学习通用策略:SGD优化方法总结
- sql优化策略总结
- 递归与分治策略
- 七牛使用总结:图片流量优化压缩策略
- 常见性能优化策略总结
- 函数的递归调用与分治策略
- zxing扫描二维码和识别图片二维码及其优化策略
- 递归与分治策略——集合划分问题,众数问题
- 递归和分治策略之二分搜索法
- 期末复习——递归与分治策略
- Java语言描述:递归与分治策略之全排列问题
- 常用排序算法完全版 快排优化 归并排序的非递归实现
- JDBC优化策略总结