简体   繁体   中英

trying to understand recursion in C

Im trying to understand how the following C code works underneath:

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

I understand that the output is the factorial of n. I guess Im trying to understand if this example of recursion is using the if statement as the cause for recursion. And can recursion for this also be performed with a for loop instead of the if? Or am I missing the point completely?

I guess Im trying to understand if this example of recursion is using the if statement as the cause for recursion.

The cause for recursion is the function calling itself. The if (n == 0) condition tells us when to stop recursing.

If we call factorial(3) , the recursion looks something like this:

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

And can recursion for this also be performed with a for loop instead of the if?

You wouldn't use a loop in this case - recursion is a type of loop in and of itself.

For computing factorials, Fibonacci numbers, etc., I will argue that an iterative algorithm (loop) is superior to a recursive algorithm:

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

as there's very little overhead compared to making n separate function calls. However, factorials are easier to express using recursive definitions:

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

so you often see it used as an example of recursion in programming. Indeed, languages like Haskell pretty much follow the mathematical notation:

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

Anything you can solve recursively you can solve iteratively, although some solutions (quicksort, tree traversals, etc.) are much easier to implement recursively.

For example, an inorder tree traverse can be written as

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

This is much simpler than trying to write a loop to visit all the nodes in the right order.

Think of it like this:

  • The factorial of 5 is (5 * factorial of 4)
  • The factorial of 4 is (4 * factorial of 3)
  • The factorial of 3 is (3 * factorial of 2)
  • The factorial of 2 is (2 * factorial of 1)
  • The factorial of 1 is 1

This is what you code is doing. When its asked for fact(1) it returns 1. Otherwise it returns n times fact(n-1) ; repeat (recurse) as needed

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM