递归与归并排序
递归
方法内部调用方法本身
将一个大型复杂的问题层层转化成一个与原问题一致的,规模小的问题,大大减少代码量。
注意的是:递归必须有边界条件,否则会发生栈内存溢出
归并排序原理(分治法)
将一组数据尽可能拆分成两组元素相等的子组,并对每一个子组进行拆分,拆到每个子组元素数量为1即可
将相邻的两个子组合并成一个有序的组,一直合并到只剩下一组为止
时间复杂度:O(nlog n)
缺陷:需要额外申请数组空间,导致空间复杂度上升,是以空间换时间的操作。
代码示例:
public class MergeSort {
public static void main(String[] args) {
Integer[] a={5,2,4,3,1};
MergeSort.sort(a);
System.out.println(Arrays.toString(a));
}
private static Comparable[] assist;
public static void sort(Comparable[] a){
assist=new Comparable[a.length];
int start=0;
int end=a.length-1;
sort(a,start,end);
}
private static void sort(Comparable[] a,int start,int end){
if (start>=end){
return;
}
int mid=start+(end-start)/2; //计算中间值
sort(a,start,mid);
sort(a,mid+1,end);
merge(a,start,mid,end);
}
private static void merge(Comparable[] a,int start,int mid,int end){
int i=start; //i指向辅助数组
int q1=start;
int q2=mid+1;
while (q1<=mid&&q2<=end){
if (a[q1].compareTo(a[q2])>0){
assist[i++]=a[q2++];
}else {
assist[i++]=a[q1++];
}
}
/*
以下是一个数组排完,剩下一个时运行,且以下两个循环只执行一个
*/
while (q1<=mid){
assist[i++]=a[q1++];
}
while (q2<=end){
assist[i++]=a[q2++];
}
/*
将辅助数组assist拷贝给原数组a
*/
for (int m=start;m<=end;m++){
a[m]=assist[m];
}
}
}