理解阶乘递归

时间:2014-04-23 18:45:21

标签: python recursion factorial

我正在查看递归的阶乘示例,并且只是想确保我正确理解它!

def factorial(n):
    if n == 0:
        return 1
    else:
        return n * factorial(n - 1)

我说得对吗?

阶乘(4)=阶乘(4-1)* 4 =阶乘(3-1)* 3 * 4 =阶乘(2-1)* 2 * 3 * 4 =阶乘(1-1)* 1 * 2 * 3 * 4 = 24

因为阶乘(1-1)=阶乘(0),其中基本情况显示= 1然后我们乘以2,然后乘以3然后乘以4。

这是看待它的正确方法吗?

提前致谢!

3 个答案:

答案 0 :(得分:6)

是的。但由于它是递归,它的工作方式正好相反。我曾经有一位面试官这样向我解释:

说,事实(5):

 - fact(5) = 5 * fact(4)
           - fact(4) = 4 * fact(3)
                     - fact(3) = 3 * fact(2)   
                               - fact(2) = 2 * fact(1)
                                         - fact(1) = 1 * fact(0) 
                                                   - fact(0) = 1
                                                   // This is where your condition returns 1.

现在,想象一下上面的-符号代表回归。你基本上会返回-符号之后的任何内容。所以从最低行返回1。然后,你实际返回1(1),即1 * 1.所以它发生在REVERSE级联中,如:

 = 120
 - fact(5) = 5 * 24
           - fact(4) = 4 * 6 = 24
                     - fact(3) = 3 * 2 = 6  
                               - fact(2) = 2 * 1 = 2
                                         - fact(1) = 1 * 1 = 1
                                                   - fact(0) = 1

请记住,无论何时进行递归,一切都会反过来。这真的可以帮助你打破任何递归问题。

这实际上是尾递归和相关优化非常重要的原因。在内存中,每个调用都会被延迟,并且在它上面的调用(图中的下方)完成并返回之前无法返回。因此,非常深的递归调用会导致堆栈溢出,除非编译器/解释器通过将其转换为OP中的版本来优化它,以便立即评估部分结果而不是延迟。 Python不执行此优化,因此您必须小心递归调用。

答案 1 :(得分:0)

是的,您所描述的方式是正在发生的事情。

您的代码需要注意的一点是,如果您输入n的非整数值或n小于0的值,则看起来您将陷入无限循环。

可能值得在代码中添加一个检查:

if not isinstance(n, int): 
      return None

 elif n < 0: 
      return None

答案 2 :(得分:0)

这可能有帮助

(factorial 4)
(4 * (factorial 3))
(4 * (3 * (factorial 3)))
(4 * (3 * (2 * (factorial 1))))
(4 * (3 * (2 * 1)))
(4 * (3 * 2))
(4 * 6)
(24)