1.从分治思想想到归并排序
我们要对一个无序的数组排序,从分治的思想出发,我们把这个无序的数组分成两部分来处理,分别排序,之后再归并到一起,得到一个完整的有序数组。显而易见,排序过程是递归的。
2.归并排序的核心要素
对子数组排序不难,递归就可以,真正需要实现的操作是归并,其实很好想,两个各自有序互不相关的数组,我们只需要分别给它们一个指针,分别遍历两个子数组,不断比较两个指针对应的值,把小的放进数组,这就ok了。
3.归并排序的思路
1.核心雏形:将数组分为左右两半,对左边排序,对右边排序,排好序之后,归并,重复这个过程。
2.通过上面第一步分析,我们想到了递归,同时因为两个子数组大小无所谓且最好差不多长,想到了二分查找。当然也发现,归并动作需要我们实现
3所谓归并是把两个各自有序的数组合并为一个有序的数组,只要各自扫描两个分组,每一个扫描指针的移动之后,都比较两个扫描指针的大小,把小的那个放进去,直到一方全部放完,把另一方放进去。因为不可能在本数组实现上述操作。我们需要一个新的辅助数组。这个描述已经十分清晰,翻译为程序语言即可。
public class Merge
{
private static int[] aux;
public static void sort(int[] a)
{
aux = new int[a.length]; //调用再创建
sort(a, 0, a.length-1);
}
private static void sort(int[] a, int low, int high)
{
if(high <= low)
return;
int mid = low + (high - low)/2;
sort(a, low, mid);
sort(a, mid+1, high);
merge(a, low, mid, high);
}
private static void merge(int[] a, int low, int mid, int high)
{
int i = low,j = mid+1;
for(int k =low; k <= high; k++)//将要处理的整个数组复制到辅助数组里面
{
aux[k] =a[k];
}
for(int k = low; k <= high; k++)//再从辅助数组归并回原数组
{
if(i > mid) //如果左边部分数组走完了,放右边的进去
{
a[k] = aux[j];
j++;
}
else if(j > high) //如果右边部分数组走完了,放左边的进去
{
a[k] = aux[i];
i++;
}
else if(aux[j] < aux[i]) //下面两个条件分句就是:谁小放谁
{
a[k] = aux[j];
j++;
}
else
{
a[k] = aux[i];
i++;
}
}
}
public static void main(String[] args)
{
int[] arr = {3,4,5,8,7,6,9,0,1,2};
Merge.sort(arr);
for(int i=0; i<10 ; i++)
{
System.out.println(arr[i]);
}
}
}