递归函数理解
代码:
package algorithms.sort;
public class MiddleSplitByRecursion {
public static void middleSplitByOneRecursion(int[] a, int lo, int hi) {
if(lo >= hi) return; //对本次输入,即上一次切分结果进行判断
int mid = lo + (hi - lo)/2;
//一直往下递归,知道不满足条件进行返回,返回到上一次递归处,继续执行后面的代码。
middleSplitByOneRecursion(a, lo, mid); //左侧切分
//每层middleSplitByOneRecursion()执行完,返回后再执行继续往下执行,即进行打印。
System.out.print(mid +" "); //先打印递归的最里层
}
public static void middleSplitByTwoRecursion(int[] a, int lo, int hi) {
if(lo >= hi) return;
int mid = lo + (hi - lo)/2;
//每一层递归有左右两个递归
middleSplitByTwoRecursion(a, lo, mid); //左侧切分
middleSplitByTwoRecursion(a, mid+1, hi); //右侧切分
//每层两个middleSplitByOneRecursion()执行完,返回后再执行继续往下执行,即进行打印。
System.out.print(mid +" "); //先打印递归的最里层
}
public static void main(String[] args) {
int[] aa = {4,5,14,6,7,98,44,56,1};
middleSplitByOneRecursion(aa, 0, aa.length-1);
System.out.println();
middleSplitByTwoRecursion(aa, 0, aa.length-1);
}
}
输出:
0 1 2 4
0 1 3 2 5 7 6 4
应用一例:归并排序
代码:
package algorithms.sort;
import algorithms.model.Smethod;
//自底而上的归并排序,是由底层小数组片段对逐步有序到全部数组有序。基本思想是归并两个短的有序数组片段为一个长度有序数组片段。
//如何找到两个有序的数组片段呢?想到两个分别含有一个元素的数组片段就是两个有序数组片段。然后不断的归并它们。
//如何找到分别只含有一个元素的数组片段呢?答案是对长数组不断地做两两切分,切分成很多层两两数组片段,逐层数组片段对越来越多,
//每对中的元素越来越少,直到每个数组对中的每个数组片段只含有一个元素。然后对这一层的所有数组片段对使用归并排序进行合并排序。
//合并后,数组对对减半,再合并该层减半的数组对,每个数组中的元素个数会加倍,重复此过程,直到返回到顶层,此时顶层已变成整个数组切分成两个
//有序的数组对,然后最后一次使用归并排序,使整个数组有序。
class Merge {
public static void merge(int[] a, int lo, int mid, int hi){
int[] auk = new int[a.length];
int i = lo;
int j = mid + 1;
for(int k = lo; k <= hi; k++)
auk[k] = a[k];
for(int k = lo; k <= hi; k++)
if(i > mid) a[k] = auk[j++];
else if (j > hi) a[k] = auk[i++];
else if (Smethod.less(auk, i, j) < 0)
a[k] = auk[i++];
else a[k] = auk[j++];
}
public static void sort(int[] a, int lo, int hi){
if(hi <= lo) return;//递归到最底层hi和lo相等,即每个数组只含有一个元素,
//此时返回到上次调用处,执行每个数组只含有一个元素的两个数组的归并。
int mid = lo + (hi - lo)/2; //切分点:偶数个元素取第一个,奇数个取中间
sort(a, lo, mid);
sort(a, mid+1, hi);//递归函数返回之前,不能往后执行
//在每一层递归中merge方法在两个sort()方法执行完成以后,即两个数组有序以后执行。
merge(a, lo, mid, hi);
}
public static void main(String[] args) {
int[] b = {1,12,13,14,5,6,17,35,56};
merge(b,0,3,8);
for(int i : b)
System.out.print(i + " ");
System.out.println();
int[] a = {11,9,2,3,4,5,11,1,71};
sort(a,0,a.length-1);
for(int i : a)
System.out.print(i + " ");
}
}
输出:
1 5 6 12 13 14 17 35 56
1 2 3 4 5 9 11 11 71