试图理解C中的递归

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了试图理解C中的递归相关的知识,希望对你有一定的参考价值。

我试图了解以下C代码如何在下面工作:

int factorial(int n) {
   int result;
   if(n==0){
       result=1;
    }else{
       result = n * factorial(n-1);
   }
   return result;
}

我知道输出是n的阶乘。我想我试图理解这个递归的例子是否使用if语句作为递归的原因。并且可以使用for循环而不是if来执行此递归吗?还是我完全忽略了这一点?

答案

我想我试图理解这个递归的例子是否使用if语句作为递归的原因。

递归的原因是调用自身的函数。 if (n == 0)条件告诉我们何时停止递归。

如果我们调用factorial(3),递归看起来像这样:

factorial(3):
  return 3 * factorial(2): -----------+
     return 2 * factorial(1); ------+ |
       return 1 * factorial(0); --+ | |
         return 1;                | | |
       1; <-----------------------+ | |
     2; <---------------------------+ |
  6; <--------------------------------+

并且可以使用for循环而不是if来执行此递归吗?

在这种情况下你不会使用循环 - 递归是一种循环本身。

对于计算阶乘,Fibonacci数等,我认为迭代算法(循环)优于递归算法:

int factorial_iter( int n )
{
  int result = 1;
  while ( n )
    result *= n--;
  return result;
}

因为与使n分开的函数调用相比,开销非常小。但是,使用递归定义更容易表达阶乘:

n! = n * n-1!, 0! = 1

所以你经常看到它被用作编程中递归的一个例子。事实上,像Haskell这样的语言几乎遵循数学符号:

factorial :: Int -> Int
factorial 0 = 1
factorial n = n * factorial( n - 1 )

你可以递归地解决任何问题,你可以迭代地解决,尽管一些解决方案(快速排序,树遍历等)更容易递归地实现。

例如,可以将顺序树遍历编写为

 /**
  * Perform an inorder traversal by
  * visiting the left subtree, then the root,
  * then the right subtree.
  */
 void inorder( node_type *t )
 {
   if ( !t )
     return;

   inorder( t->left );
   do_something_with( t->data );
   inorder( t->right );
 }

这比尝试编写循环以正确顺序访问所有节点要简单得多。

另一答案

可以这样想:

  • 阶乘数为5(5 *阶乘4)
  • 阶乘4是(4 *阶3)
  • 阶乘3是(3 *阶乘2)
  • 阶乘2是(2 *阶乘1)
  • 阶乘1是1

这就是你的代码正在做的事情。当它要求fact(1)时它返回1.否则它返回n次fact(n-1);根据需要重复(递归)

以上是关于试图理解C中的递归的主要内容,如果未能解决你的问题,请参考以下文章

如何理解二叉树中的递归

精心收集的 48 个 JavaScript 代码片段,仅需 30 秒就可理解!(转载)

我在 laravel 中的递归函数不调用自己

JavaScript:试图理解计算指数值的递归函数的 Else 语句

Blazor 中的递归标记

递归 - 试图理解