如何理解java中的递归概念?

时间:2014-09-25 14:46:45

标签: java recursion concept

我是java编程的新手,我们的老师教我们递归的概念,我发现它有点复杂。我只知道它就像一个循环(就像4的阶乘),但我仍然不明白它为什么会这样。我可以获得有关此主题的详细说明吗?这是我的老师用来解释的代码和图片。

package javaapplication1;

public class JavaApplication1 {

static int factorial(int n){
    int t;
    if(n == 0){
        return 1;
    } else {
        t = factorial(n - 1);
        return n * t;
    }
}
public static void main(String[] args) {
    System.out.println(factorial(5));
    }
}

在下图中,蓝色表示堆叠缠绕,绿色表示堆叠展开,我不知道堆叠缠绕和展开是什么。

http://i.stack.imgur.com/pjqJy.png

6 个答案:

答案 0 :(得分:1)

当调用另一个方法时,会创建一个堆栈帧来保存当前方法的状态,并将其推入堆栈。这与调用自身的方法或其他方法无关。

当调用返回时,堆栈框架将弹出堆栈,方法的状态将恢复,并在调用方法中继续执行。

递归是指一种方法(直接或间接)调用自身。递归方法的一般形式是:

  • 如果参数符合终止条件,则返回(通常是结果)
  • 否则调整下一次迭代的参数并调用self

你老师写的代码有一些风格问题。如果这样写的话会更清楚:

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

根除不必要的变量t和冗余else(当“if”返回时没有“else” - 只有继续执行)

我会这样写,完全取消if

static int factorial(int n) {
    return n == 0 ? 1 : n * factorial(n - 1);
}

答案 1 :(得分:1)

递归函数是一个函数,它调用自身直到它到达一个return语句,这会阻止它自己调用。举个例子,Factorial函数。 因子是一个数学函数,它返回乘以其自身的数字 - 1乘以其自身 - 2,...乘以1,例如:5的因子= 5! = 5x4x3x2x1 = 120。 它也等于自身乘以阶乘-1,即:5! = 5x4! 考虑到0! = 1。 要在Java代码中表示这一点,您需要一个循环,将从1开始的数字相乘,直到计算其阶乘的数字。 更进一步,解释你的代码,让我们计算Factorial(5): Factorial()返回一个整数。

  

从main()初始调用:5!= 0,然后跳过条件(n == 0); Ť   =阶乘(5-1)=阶乘(4);

     

来自Factorial(4)的第二次调用:4!= 0,然后跳过条件(n ==   0); t =因子(4-1)=因子(3);

     

来自Factorial(3)的第三次调用:3!= 0,然后跳过条件(n ==   0); t =因子(3-1)=因子(2);

     

来自Factorial(2)的第四次调用:2!= 0,然后跳过条件(n ==   0); t =因子(2-1)=因子(1);

     

来自Factorial(1)的第五次调用:1!= 0,然后跳过条件(n ==   0); t =因子(1-1)=因子(0);

     

来自Factorial(0)的第六次调用:0 == 0,然后返回值1;

     

第一次返回,1,到第五次调用(因子(1)):返回n * t =返回1 * 1   =返回值1;

     

第二次返回,1,到第四次调用(Factorial(2)):return n * t = return   2 * 1 =返回值2;

     

第三次返回,2次到第三次调用(因子(3)):返回n * t =返回3 * 2   =返回值6;

     

第二次返回,6,到第二次调用(Factorial(4)):return n * t = return   4 * 6 =返回值24;

     

第二次返回,24,到第一次调用(Factorial(5)):return n * t = return   5 * 24 =返回值120;

     

第二次返回,120,到初始调用(从main()):print(120);

希望这有助于您理解递归。

答案 2 :(得分:0)

当一个人知道一个任务可以被分解成类似的小任务时,我们就会使用递归或调用相同的方法(直到我们遇到某个条件)。Recursion不仅有助于执行问题而不需要要定义或调用另一个方法,它还有助于可视化执行任务的模式

答案 3 :(得分:0)

就个人而言,我不喜欢阶乘问题。我觉得很难理解,我不认为它以明确的方式解释递归。让我们看一个不同的例子。让我们说我们要打印1-100的数字。这是一个非常简单的任务,有一个for循环和一个计数器,但它也可以用递归完成。例如:

public static void main(String[] args) {
    numbersAscending(1);
    numbersDescending(1);   
}
//Prints 1 2 3 ... 100
public void numbersAscending(int x){
    System.out.println(x);
    if(x < 100){
        numbersAscending(x+1);
    }
}
//Prints 100 99 98 ... 1
public void numbersDescending(int x){
    if(x < 100){
        numbersDescending(x+1);
    }
    System.out.println(x);
}

调用函数时,该调用将在堆栈顶部进行。把它想象成一堆卡片。每个人都有一个数字(1-100)。当函数调用自身时,会将新卡添加到堆栈中。当函数完成时,它将从堆栈中取出。

因此,对于上面的示例,每次调用numbersAscending时,它都会在再次调用该函数之前打印出x的当前值。这导致数字按1-100的顺序打印。一旦达到100,它就会停止调用自身并将每个函数从堆栈中弹出。

另一方面,每次调用numbersDescending时,它会在打印出数字之前再次调用自身。这样,x直到达到100才开始打印。然后它向下移回堆栈,打印每个数字,直到它返回到main方法。

答案 4 :(得分:0)

/*This program in java will help you to understand all the basics of 
  recursion:
  ->how control flows in recursion
  ->how return is executed in the recursive functions
  ->how and when the statements after recursive function area executed.*/

public class Understanding_Rec{

public static int rec(int x)
{
    if(x<5)
    {
        System.out.println("-->Smaller than 5");
        rec(x+1);
        System.out.println("<--After recursion inside x<5");
        return x;
    }
    else if(x<7)
    {
        System.out.println("-->Smaller than 7");
        rec(x+1);
        System.out.println("<--After recursion inside x<7");
    }
    System.out.println("<--No Condition Statement");
    return x;
}

public static void main(String[] args)
{
    int x=1;
    rec(x);
    System.out.print(x+"Inside main");
}
}

答案 5 :(得分:-1)

我不确定它是否解释,但是如果你有一个预分类,那么你应该知道可以用两个方程来定义阶乘。

N!= 1 * 2 * ... * N

我们定义

1!= 1

N!= N *(N-1)!

试着看看自己那些定义是等价的。让我们说,5!

根据第二个定义

5!= 5 * 4!

但是4!= 4 * 3!所以5!= 5 * 4 * 3!

但是3!= 3 * 2!所以5!= 5 * 4 * 3 * 2!

等等。继续这样做直到你达到1!但是1!= 1所以你停下来。

编程中的递归是一回事。

TomW