可能是重复问题:
递归函数的例子
我一直在研究编程中递归的概念(尽管我特别研究Java),以下是我最好理解的内容:
比如,现实生活中,当我们把两个镜子放在一起时,它们之间产生的图像就是递归的。
但我不明白编程中的这个算法? 请给我一个简单的例子来理解递归?
可能是重复问题:
递归函数的例子
我一直在研究编程中递归的概念(尽管我特别研究Java),以下是我最好理解的内容:
比如,现实生活中,当我们把两个镜子放在一起时,它们之间产生的图像就是递归的。
但我不明白编程中的这个算法? 请给我一个简单的例子来理解递归?
递归是一种编程技术,其中一个方法可以在计算过程中调用自身(有时可能会有多个方法 - 这些方法通常会相互循环调用)。
一个流行的例子是计算斐波那契数列:
public static long fib(int n) {
if (n <= 1) return n;
else return fib(n-1) + fib(n-2);
}
两个基本组成部分是基本情况(例如示例中的n<=1
)和递归情况。
在创建递归算法时,您需要考虑基本情况以及如何使用递归情况来达到基本情况(否则会出现无限递归并使堆栈崩溃)。
基本上,当一个函数满足以下两点时,它就是递归的:
例如,计算阶乘:
public static long factorial(int i)
{
// This is the base case
if(i == 0)
{
return 1;
}
else
{
// This reduces the problem to something closer to the base case
return i * factorial(i - 1);
}
}
pow(a, b){
if(b == 0){
return 1;
}else{
return a * pow(a, b - 1);
}
}
需要注意的是,这只是递归的基本概念。你在各种答案中看到的斐波那契数列问题等示例非常低效。你可以使用动态规划技术构建更高效的程序,其中递归是解决问题的机制之一。
int fact(int n) {
if (n < 2) {
return 1;
}
return n * fact(n-1);
}
n
减 1)。一个方法可以调用自身,这就是递归。经常使用方法的递归实现,因为它们会导致紧凑优雅的代码,比不使用递归的相应实现更容易理解。
递归编程技巧知道三个重要的规则(经验):
从性能的角度来看,非递归解决方案更快,通常需要更少的内存。(例如二分查找)
但是,有些任务如此复杂,只有递归解决方案才能得到(更或多或少可理解的)代码。
递归二分查找的示例:
public static int binSearch(int[] a, int key) {
return binSearch0(a, key, 0, a.length - 1);
}
public static int binSearch0(int[] a, int key, int from, int to) {
if (from > to) return -1;
// looks strange but (from + to) / 2 can oveflow
// (java bug which was active more than 10 years)
int mid = from + (to - from) / 2;
if (key < a[mid])
return binSearch0(a, key, from, mid - 1);
else if (key < a[mid])
return binSearch0(a, key, mid + 1, to);
else return mid;
}
非常简单的“递归”代码。
处理列表的顶部项目。从列表中删除它并调用处理列表顶部项目的代码。
树根具有一定长度,并在每2/3个根处分裂成单独的根。分裂的块再次在每2/3个根处分裂成单独的根。分裂块的分裂块再次分裂..等等。