本文要讲的归并排序是继快速排序之后的又一常用排序算法,相似的是归并排序也是一种分治算法,因此,与快排一样,对于规模较大的问题,非常适用。
与快排相比,归并排序是稳定的,最重要的是其优点在于,其最差时间复杂度也是O(NlogN)。
归并排序是将两个(两个以上按两两处理)有序表合并成一个新的有序表。这里要强调下,待归并的两个数列必须是有序的。具体原因见算法。
算法思想:
1.首先将原数列,分解成左右两部分
2.分别对左右两部分,进行分解处理
3.再讲子部分合并成为一个有序数列
代码框架如下:
static void merge(int[] a,int begin ,int end){ if(begin == end){//只有一个元素的时候,认为已经排好序,跳出递归 return; } if(begin<end){ int mid = (begin + end)/2; //分解左半部分和右半部分 1. merge(a,begin,mid); 2. merge(a,mid+1,end); //将分解处理之后的部分进行合并 3. mergeAndSort(a,begin,mid,end); } }
如果对递归不是特别熟悉的话,可以结合这个例子,手动的画出递归栈
↓ begin ↓ mid ↓ end
5 | 4 | 2 | 7 | 9 | 1 |
接下来的重点是merge:
比如说
a的左半部分是:1 3 8,赋值给left[]
a的右半部分是:2 4 5,赋值给right[]
为了方便对比,我们将left和right的最后加一个哨兵元素MAX,这样就不比对最后一个元素做特殊处理了。
static void mergeAndSort(int[] a,int begin,int mid,int end){ int[] left = new int[mid - begin + 2]; //多留出一个哨兵位 int[] right = new int[end - mid + 1]; for(int i = begin ; i <= end; i++){ if(i <= mid){ left[i - begin] = a[i]; }else{ right[i - mid - 1] = a[i]; } } left[mid - begin + 1] = Integer.MAX_VALUE; right[end - mid] = Integer.MAX_VALUE; int i = 0; int j = 0; int index = begin; while(index <= end){//按照顺序,将左右两部分归并 a[index++] = left[i] < right[j] ? left[i++] : right[j++]; } }
附录:
全部源代码为:
package sort; import java.util.Arrays; public class Merge { static void merge(int[] a,int begin ,int end){ if(begin == end){ return; } if(begin<end){ int mid = (begin + end)/2; merge(a,begin,mid); merge(a,mid+1,end); mergeAndSort(a,begin,mid,end); } } static void mergeAndSort(int[] a,int begin,int mid,int end){ int[] left = new int[mid - begin + 2]; int[] right = new int[end - mid + 1]; for(int i = begin ; i <= end; i++){ if(i <= mid){ left[i - begin] = a[i]; }else{ right[i - mid - 1] = a[i]; } } left[mid - begin + 1] = Integer.MAX_VALUE; right[end - mid] = Integer.MAX_VALUE; int i = 0; int j = 0; int index = begin; while(index <= end){ a[index++] = left[i] < right[j] ? left[i++] : right[j++]; } } public static void main(String[] args) { int[] a = {1,9,5,7,4,6,3,8,11,24}; merge(a,0,a.length - 1); System.out.println(Arrays.toString(a)); //打印结果为:[1, 3, 4, 5, 6, 7, 8, 9, 11, 24] } }
相关推荐
自动生成500个随机数,然后对这500个随机数进行归并排序
算法-归并排序(java)(csdn)————程序
归并排序 在排序前,先建好一个长度等于原数组长度的临时数组
(10)数据结构之红黑树(三)——删除操作 (11)排序算法(一)——冒泡排序及改进 (12)排序算法(二)——选择排序及改进 (13)排序算法(三)——插入排序及改进 (14)排序算法(四)——归并排序与递归...
算法分类:排序算法(如冒泡排序、快速排序、归并排序),查找算法(如顺序查找、二分查找、哈希查找),图论算法(如Dijkstra最短路径算法、Floyd-Warshall算法、Prim最小生成树算法),动态规划,贪心算法,回溯法...
java代码-使用java解决java排序之-归并排序的问题的源代码 ——学习参考资料:仅用于个人学习使用!
小白日记之八种排序算法——八种排序算法:冒泡排序、选择排序、插入排序、希尔排序、基数排序、堆排序、归并排序、快排
NULL 博文链接:https://yuan.iteye.com/blog/308778
堆6.6 左式堆6.6.1 左式堆性质6.6.2 左式堆操作6.7 斜堆6.8 二项队列6.8.1 二项队列结构6.8.2 二项队列操作6.8.3 二项队列的实现6.9 标准库中的优先队列小结练习参考文献第7章 排序7.1 预备知识7.2 插入排序7.2.1 ...
《数据结构与算法分析:Java语言描述(第2版)》是国外数据结构与算法分析方面的经典教材,使用卓越的Java编程语言作为实现工具讨论了数据结构(组织大量数据的方法)和算法分析(对算法运行时间的估计)。...
堆6.6 左式堆6.6.1 左式堆性质6.6.2 左式堆操作6.7 斜堆6.8 二项队列6.8.1 二项队列结构6.8.2 二项队列操作6.8.3 二项队列的实现6.9 标准库中的优先队列小结练习参考文献第7章 排序7.1 预备知识7.2 插入排序7.2.1...
算法分类:排序算法(如冒泡排序、快速排序、归并排序),查找算法(如顺序查找、二分查找、哈希查找),图论算法(如Dijkstra最短路径算法、Floyd-Warshall算法、Prim最小生成树算法),动态规划,贪心算法,回溯法...
堆6.6 左式堆6.6.1 左式堆性质6.6.2 左式堆操作6.7 斜堆6.8 二项队列6.8.1 二项队列结构6.8.2 二项队列操作6.8.3 二项队列的实现6.9 标准库中的优先队列小结练习参考文献第7章 排序7.1 预备知识7.2 插入排序7.2.1 ...
练习 参考文献第7章 排序 7.1 预备知识 7.2 插入排序 7.2.1 算法 7.2.2 插入排序的分析 7.3 一些简单排序算法的下界 7.4 希尔排序 7.5 堆排序 7.6 归并排序 7.7 快速排序 7.7.1 选取枢纽元 ...
练习 参考文献第7章 排序 7.1 预备知识 7.2 插入排序 7.2.1 算法 7.2.2 插入排序的分析 7.3 一些简单排序算法的下界 7.4 希尔排序 7.5 堆排序 7.6 归并排序 7.7 快速排序 7.7.1 选取枢纽元 ...
本文件讲了十种JAVA排序方法(冒泡(Bubble)排序——相邻交换 、选择排序——每次最小/大排在相应的位置 、插入排序——将下一个插入已排好的序列中 、壳(Shell)排序——缩小增量 、归并排序 、快速排序 、堆排序 ...
- 归并排序 - 快速排序 ###第八章 -不相交集 ###第九章 -邻接表(Versioni 1,2) -拓扑排序(Versioni 1,2) -单源最短路径算法 -最大网络流 -最小生成树 -深度优先搜索 -双连通性 -欧拉回路 ###第十章 -分治算法:最近...
算法分类:排序算法(如冒泡排序、快速排序、归并排序),查找算法(如顺序查找、二分查找、哈希查找),图论算法(如Dijkstra最短路径算法、Floyd-Warshall算法、Prim最小生成树算法),动态规划,贪心算法,回溯法...
归并排序 Merge Two Sorted Arrays Merge Two Sorted Lists Merge k Sorted Lists Sort List 快速排序 Sort Colors Kth Largest Element in an Array 桶排序 First Missing Positive 计数排序 H-Index 基数排序 ...