如何理解递归
本质上是将原来的问题转化为更小的同样的问题,问题的规模可以逐渐缩小,通常小到不能再小的时候,会更加容易的解决。
举一个简单的例子:数组求和
Sum(arr[0...n-1]) = arr[0]+Sum(arr[1...n-1])
得到一个更小同一问题
求数组中n个数的和,其实等于把索引为0的数拿出来加上第1到n-1所有元素的和。在这两个Sum函数中,第二个sum要比第一个更小,因为第一个sum需要求n个数的和,而第二个只需要对n-1个数求和。
上述过程依次类推Sum(arr[1...n-1]) = arr[1]+Sum(arr[2...n-1])
得到更小统一问题- ······
Sum(arr[n-1...n-1]) = arr[n-1]+Sum(arr[])
最基本的问题
对一个数字求和就等于这个数组加上对空数组求和,空数组的和为0。
将最基本的问题解决了之后,根据上面所述的一系列逻辑就可以将原问题解决。
使用递归解决数组求和
Sum.java
public class Sum {
// 用户操作的函数
public static int sum(int[] arr) {
// 递归的初始调用是从0开始到n-1
return sum(arr, 0);
}
// 计算arr【l...n)这个区间所有数字的和 l-(n-1)的和
// 真正的递归的函数
private static int sum(int[] arr, int l) {
// 当左边界l等于数组长度的时候 即整个数组为空的时候
if (l == arr.length)
return 0;
return arr[l] + sum(arr, l + 1);
}
// 声明一个数组进行main函数测试
public static void main(String[] args) {
int[] nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
System.out.println(sum(nums));
}
}
测试结果:
55
递归算法的基本原则
通过数组求和完成了一个递归函数sum()
private static int sum(int[] arr, int l) {
if (l == arr.length)
return 0;
return arr[l] + sum(arr, l + 1); // 让arr[l] 加更小的一段数组中所有元素的和
}
所有的递归算法都是可以分成两部分:
求解最基本的问题
,这个问题是需要编写逻辑求解的。通常最基本问题都是非常简单的。把原问题转化成更小的问题
,也是递归算法最核心的部分。不是简单的求一个更小的问题的答案,而是根据更小问题的答案构建出原问题的答案。
在写递归函数时一定要注重递归函数本身的语意。
对于求和sum来说,它本身就是计算l…n-1之间所有数字的和。(递归函数的宏观语意)递归函数本身也是一个函数,完成一个功能。把需要调用的递归函数想像成一个子过程,思考子过程如何帮助自己解决问题。