递归过程中到底发生了什么?
谁能告诉我递归程序中到底发生了什么..?
Can anyone tell me what exactly happens in a Recursion Program.. ??
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
谁能告诉我递归程序中到底发生了什么..?
Can anyone tell me what exactly happens in a Recursion Program.. ??
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(6)
与迭代相反,递归是一种算法或函数设计,其中函数调用自身。这可以使函数更容易理解,但也会使其变慢,因为必须创建一个新的堆栈。此外,堆栈内存使用量将随着每次调用而线性增加。
另一方面,迭代在一个函数中循环遍历所有内容,将时间复杂度保持在 O(n),并且空间复杂度固定并且不会随着每次迭代而增加。
例如,考虑一个将连续数字相加的函数。请注意,有一个公式可以通过一个简单的计算(时间复杂度为 O(1))来完成此操作,但我们仅以此为例。
递归函数可能如下所示:
通过此递归调用,您可能很快就会耗尽堆栈内存。然而,迭代模型对此更好:
Recursion, as opposed to iteration, is an algorithm or function design where a function calls itself. This could make a function a lot easier to understand, but makes it slower because a new stack must be created. Also, the stack memory usage will increase linearly with each call.
Iteration, on the other hand, loops through all in one function, keeping the time complexity at O(n), and the space complexity fixed and not increasing with each iteration.
For example, consider a function that adds consecutive numbers. Note that there's a formula to do this in one simple calculation (with O(1) time complexity) but let's just do this as an example.
The recursive function might look like this:
You could run out of stack memory very quickly with this recursive calling. However, the iterative model is better for this:
递归程序可能如下所示:
(python)
问题是,会发生什么?答案是最好从函数的角度来思考这个问题并尝试将它们写出来。
因此,我们有语句 print
f(7)
。为了找出它的计算结果,我们通过该函数运行7
并发现它的计算结果为f(8)
。好的,很好,但是它的评估结果是什么?f(9)
。我故意在这里有一个 exit 子句 - 最终i
在循环中将等于 100,这将是返回的值。会发生什么:f(7) = ?
f(7) = f(8) = ?
f(7) = f(8) = f(9 ) = ?
f(7) = f(8) = f(9) = f(10) = ?
...
f( 7) = f(8) = ... = 100
f(7) 是 100
这是一个相当简单的示例,但确实很好地演示了递归。
A recursive program might look like this:
(python)
The question is, what happens? The answer is it is better to think about this in terms of functions and try to write them out.
So, we have the statement print
f(7)
. In order to find out what this evaluates to, we run7
through the function and find out it evaluates tof(8)
. Ok great, but what is does that evaluate to?f(9)
. I have an exit clause in here deliberately - eventuallyi
will equal 100 in the loop and that will be what is returned. What happens:f(7) = ?
f(7) = f(8) = ?
f(7) = f(8) = f(9) = ?
f(7) = f(8) = f(9) = f(10) = ?
...
f(7) = f(8) = ... = 100
f(7) is 100
This is a fairly trivial example but does demonstrate recursion quite well.
递归示例:
在此示例中,当 foo 被以 true 调用时,它会再次以 false 调用自身。因此,您将收到两条带有上述代码的警报消息。函数foo调用函数foo的地方就是递归。
An example of recursion:
In this example, when foo gets called with true, it calls itself again with false. So, you will get two alert messages with the above code. The bit where the function foo calls the function foo is recursion.
正如其他人提到的,递归只是一个调用自身的方法。这有几个优点,但也有一些缺点。
作为示例,阶乘的典型计算:
迭代版本:
递归版本:
正如您所看到的,代码更短并且更容易阅读(如果您习惯递归)。
现在让我们检查堆栈:
1:1 变量的阶乘(因子)
2 的阶乘:2 个变量(因子和阶乘的返回值(因子 - 1))
3 的阶乘:3 个变量(因子,阶乘(因子 -1)的返回值,它具有另一个阶乘(因子 - 1)的返回值)
...
它看起来大致像这样
正如你所看到的,递归需要更多的堆栈空间(你必须添加返回指针、变量的压入和弹出以及函数调用所需的其他一些东西)并且通常会更慢。空间问题可以通过使用尾部优化递归来减少,但这对这篇文章来说太大了,但为了完整性,优化版本将如下所示:
递归真正有用的唯一地方是(恕我直言)遍历树结构。
As others mentioned recursion is just a method calling itself. This has several advantages but also some disadvantages.
As Example the typical calculation of factorials:
Iterative version:
Recursive version:
As you can see the code is a little shorter and slightly easier to read (if you are used to recursion).
Now lets check the stack:
factorial of 1: 1 variable (factor)
factorial of 2: 2 variables (factor and return value of factorial(factor - 1))
factorial of 3: 3 variables (factor, return value of factorial(factor -1) which has the return value of another factorial(factor - 1))
...
It looks rougly like this
As you can see recursion requires more space on the stack (you have to add the return pointers, push and pop of variables and some other stuff a function call requires) and it is usually slower. The space problem can be reduced by using tail-optimized recursion, but thats too big a topic for this post, but just for completeness, an optimized version would look like this:
The only place where recursion is really helpful is (IMHO) walking through tree structures.
函数调用自身。这可以用来代替迭代,但通常效率较低,因为必须为每个函数调用分配新的堆栈。
A function calls itself. This can be used instead of iteration, but is generally less efficient as a new stack has to be allocated for each function call.
函数会一遍又一遍地调用自身,直到满足某些条件。
一个愚蠢的例子:如何递归地走 100 步:
这就是发生的情况:
可以使用循环(“迭代”)完成同样的事情:
程序流程会有点不同,但结果是相同的:
请注意, 不能说递归和迭代哪个更好。在这个例子中,迭代(循环)比递归写起来更简单,也更容易理解;在其他情况下(例如遍历树结构),递归可能是更好的解决方案。
A function calls itself over and over, until some condition is met.
A silly example: How to walk 100 steps recursively:
This is what happens:
Note that the same thing could be accomplished with a loop ("iteratively"):
The program flow would be a bit different, yet the result is the same:
It cannot be said whether recursion or iteration is always better. In this example, iteration (loop) is simpler to write and easier to understand than recursion; in other cases (e.g. traversing tree structures), recursion may be a better solution.