试图了解C中的递归

时间:2018-12-10 22:14:18

标签: c recursion

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

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

我知道输出是n的阶乘。我猜我想了解递归的示例是否使用if语句作为递归的原因。并且可以使用for循环而不是if来执行此递归吗?还是我完全忘记了要点?

2 个答案:

答案 0 :(得分:4)

  

我想我想了解递归的示例是否使用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来执行此递归吗?

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

对于计算阶乘,斐波那契数等,我将认为迭代算法(循环)优于递归算法:

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 );
 }

这比尝试编写一个循环以正确的顺序访问所有节点要容易得多。

答案 1 :(得分:2)

这样想:

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

这就是您的代码正在执行的操作。当要求输入{ "code" : 401, "errors" : [ { "domain" : "androidpublisher", "message" : "The current user has insufficient permissions to perform the requested operation.", "reason" : "permissionDenied" } ], "message" : "The current user has insufficient permissions to perform the requested operation." } 时返回1。否则返回n次fact(1);否则返回n次。根据需要重复(递归)