分而治之是设计高效算法的一个重要思想。本文主要总结一下分治思想在排序算法中的运用。
排序在商业数据处理和现代科学计算中有着重要的地位,它能够应用于事物处理、组合优化、天体物理学、分子动力学、语言学、基因组学、天气预报和很多其它领域。——《算法》。
发展至今,已经出现过很多的排序算法。如选择排序,插入排序,希尔排序,堆排序,归并排序,快速排序。这里主要总结下后面种,这种也是目前运用最广和最高效的(虽然在某些特殊情况下,前面一些算法的效率更加高,但这里主要是针对一般情况下),这2种排序是分治思想的典型运用(分治思想也就是把大问题转化为小问题,然后分别去解决,最后整体归并)。
一、归并排序
归并,即将2个有序的数组归并成一个更大的有序数组。而不管是归并排序还是快速排序都是基于归并进行操作的。
1.自顶向下的归并排序。
具体思想是先将左半边排序,然后将右半边排序,最后将排序好的结果归并起来。
如下
private static void sort(Comparable[] a,int lo,int hi) {
if (hi <= lo) return;
int mid = lo+(hi-lo)/2;
sort(a,lo,mid); // 将左半边排序
sort(a,mid+1,hi); // 将右半边排序
merge(a,0,mid,hi); // 将排序好的结果归并
}
注意进行归并操作时,需要使用一个辅助数组。首先把需要排序的所有元素放入到一个辅助数组中,归并时需要进行4个判断:如果左半边的元素取完就取右半边的元素;如果右半边的元素取完就取左半边的元素;如果右半边的当前元素小于左半边
的当前元素则取右半边的元素;如果左半边的当前元素大于右半边的当前元素则取左半边的元素。
最后看总体代码
public class MergeSort {
// 定义一个辅助数组
private static Comparable[] aux;
public static void sort(Comparable[] a) {
// 分配辅助数组所需的空间
aux = new Comparable[a.length];
sort(a,0,a.length-1);
}
private static void sort(Comparable[] a,int lo,int hi) {
if (hi <= lo) return;
int mid = lo+(hi-lo)/2;