int fact(int a)
{
if(a==1)
return 1;
return a*fact(a-1);
}
In general, recursion isn't necessarily fast (function call overhead tends to be high because recursive functions tend to be small, see above) and can suffer from some problems (stack overflow anyone?). Some say they tend to be hard to get 'right' in non-trivial cases but I don't really buy into that. In some situations, recursion makes the most sense and is the most elegant and clear way to write a particular function. It should be noted that some languages favor recursive solutions and optimize them much more (LISP comes to mind).
I think that because it's an interesting technique, some coders perhaps end up using it more often than they should, without real justification. This has given recursion a bad name in some circles.
The canonical example is a routine to generate the Factorial of n. The Factorial of n is calculated by multiplying all of the numbers between 1 and n. An iterative solution in C# looks like this:
public int Fact(int n)
{
int fact = 1;
for( int i = 2; i <= n; i++)
{
fact = fact * i;
}
return fact;
}
迭代解决方案没有什么令人惊讶的地方,对于任何熟悉 C # 的人来说,它应该是有意义的。
通过识别第 n 阶乘是 n * Fact (n-1) ,可以找到递归解。或者换句话说,如果你知道一个特定的阶乘数是多少,你就可以计算下一个阶乘数。下面是 C # 中的递归解决方案:
public int FactRec(int n)
{
if( n < 2 )
{
return 1;
}
return n * FactRec( n - 1 );
}
这个函数的第一部分被称为 基本情况(有时是警卫子句) ,它阻止算法永远运行。每当调用值为1或小于1的函数时,它只返回值1。第二部分更有趣,被称为 递归步骤。这里我们用一个稍微修改过的参数调用相同的方法(我们将它减1) ,然后将结果与 n 的副本相乘。
That final substitution happens when the base case is triggered. At this point we have a simple algrebraic formula to solve which equates directly to the definition of Factorials in the first place.
the recursive rule, which states what happens if you still have data. This is usually some kind of rule that says "do something to make your data set smaller, and reapply your rules to the smaller data set."
如果我们将上面的代码转换为伪代码,我们得到:
numberOfItems(set)
if set is empty
return 0
else
remove 1 item from set
return 1 + numberOfItems(set)
For instance, to calculate a factorial for the number X, one can represent it as X times the factorial of X-1. Thus, the method "recurses" to find the factorial of X-1, and then multiplies whatever it got by X to give a final answer. Of course, to find the factorial of X-1, it'll first calculate the factorial of X-2, and so on. The base case would be when X is 0 or 1, in which case it knows to return 1 since 0! = 1! = 1.
Recursion is the process where a method call iself to be able to perform a certain task. It reduces redundency of code. Most recurssive functions or methods must have a condifiton to break the recussive call i.e. stop it from calling itself if a condition is met - this prevents the creating of an infinite loop. Not all functions are suited to be used recursively.
假设你有三个经理——杰克、约翰和摩根。
Jack manages 2 programmers, John - 3, and Morgan - 5.
你会给每个经理300美元,并想知道它的成本。
The answer is obvious - but what if 2 of Morgan-s employees are also managers?
start
Is the table empty?
yes: Count the tally marks and cheer like it's your birthday!
no: Take 1 apple and put it aside
Write down a tally mark
goto start
Any algorithm exhibits 结构性的 recursion on a datatype if basically consists of a switch-statement with a case for each case of the datatype.
例如,当您正在处理类型时
tree = null
| leaf(value:integer)
| node(left: tree, right:tree)
结构递归算法的形式
function computeSomething(x : tree) =
if x is null: base case
if x is leaf: do something with x.value
if x is node: do something with x.left,
do something with x.right,
combine the results
这确实是最明显的方式来编写任何运行在数据结构上的算法。
现在,当您查看使用 Peano 公理定义的整数(自然数)时
integer = 0 | succ(integer)
可以看到整数的结构递归算法如下所示
function computeSomething(x : integer) =
if x is 0 : base case
if x is succ(prev) : do something with prev
In programming terms, when a function or method calls itself repeatedly, until some specific condition gets satisfied, this process is called Recursion. But there must be a terminating condition and function or method must no enter into an infinite loop.
A child couldn't sleep, so her mother told her a story about a little frog,
who couldn't sleep, so the frog's mother told her a story about a little bear,
who couldn't sleep, so the bear's mother told her a story about a little weasel...
who fell asleep.
...and the little bear fell asleep;
...and the little frog fell asleep;
...and the child fell asleep.
A method is recursive if it can call itself; either directly:
void f() {
... f() ...
}
或间接地:
void f() {
... g() ...
}
void g() {
... f() ...
}
2)何时使用递归
Q: Does using recursion usually make your code faster?
A: No.
Q: Does using recursion usually use less memory?
A: No.
Q: Then why use recursion?
A: It sometimes makes your code much simpler!