具有两个变量的Java递归

具有两个变量的Java递归,java,recursion,Java,Recursion,我一直在试图弄清楚这个递归方法的堆栈是什么样子的 public class Apples { public static void main (String [] args) { q1(5); } public static int q1 (int x) { if (x < 1) { System.out.println(x); return 1; }

我一直在试图弄清楚这个递归方法的堆栈是什么样子的

public class Apples {

    public static void main (String [] args) {
       q1(5);   
    }

    public static int q1 (int x) {
        if (x < 1) {
            System.out.println(x);
            return 1;
        }
        int a = 3 + q1(x / 2);
        int b = 2 * q1(x - 2) + 1;
        System.out.println(x + ";" + a + ";" + b);
        return a + b;
    }
}

这显然既不正确也不完整。请帮助我了解堆栈是如何建立的。

要知道实际的调用转换从
q1(0),q1(1)…开始。

我可以为您提供
q1(2)
,然后您可以轻松尝试
q1(5)


因此,您可以打印
q1(2)
,并将得到输出
13
。调试将帮助您更好地理解

理论

每次,此函数都会先沿
q1(x/2)
路径递归,直到达到结束条件。然后,将处理所有挂起的
q1(x-2)
调用。现在这就是问题的症结所在,每次
q1(x-2)
我们首先处理
q1(x/2)
。因此,我们现在回到了以前的位置,只向下一层,重复直到我们处理所有
q1(x-2)
调用(在最后的
q1(x/2)
层)

有一种方式认为它就像一棵树:

我只认为堆栈是根据x/2增长的

你是对的,如果你是说这个函数在
q1(x/2)
方向的递归速度比
q1(x-2)
方向的递归速度快得多。尽管如此,您所说的意味着它以lg(n)的方式增长(lg(n)是基数2)

但是,我们仍然需要分析其他堆栈帧,因此我们设置了以下递归关系:


T(n)=T(n/2)+T(n-2)+c1

由于重复进行递归调用以计算
a的值,此递归函数的堆栈最初将增长;也就是说,我们将继续调用
q1(x/2)
,直到
x/2<1
,在这种情况下,我们已经到达递归的基本情况,可以简单地返回1

每次我们从一个初始
q1(x/2)
调用返回时,我们都必须遵循为计算
b
而进行的
q1(x-2)
调用。该递归调用还将对
a
进行一系列连续的递归调用(因为
a
是在函数中首先计算的),它们遵循相同的规则;在每次返回后,我们对
b
进行递归调用,这个过程会重复,直到在所有调用分支中都达到基本情况

下面是堆栈的外观。读入的顺序是:首先尽可能沿着垂直箭头,返回,然后沿着对角箭头。按照对角箭头重复此过程。当没有箭头跟随时,返回

顺便说一句,返回函数的堆栈帧将被完全释放,如果进行了新的函数调用,将替换它。您可以看到,在任何给定时间,活动的堆栈帧不超过4个。当最后一个最上面的堆栈帧完成时,它将被释放,其位置将被下面和右边的堆栈占据。你从那里回来,等等

希望这张图表能帮助我们理清思路

                |                  |                  |
                |                  |                  |
                |                  |                  |
  +--------+    |                  |                  |
  | a =    |    |                  |                  |
  | b =    |    |                  |                  |
  +--------+    |                  |                  |
  | x = 0  |
  +--------+
  returns 1 

       ^             +--------+
       |             | a =    |
       |             | b =    |
       |             +--------+
       |          /  | x = -1 |
       |         /   +--------+
       |        /    returns 1
       |       /
  +--------+  /            
  | a = 4  | /             
  | b = 3  |/              
  +--------|               
  | x = 1  |               
  +--------+               
  returns 7                

       ^             +--------+
       |             | a =    |
       |             | b =    |
       |             +--------+
       |          /  | x = 0  |
       |         /   +--------+
       |        /    returns 1
       |       /
  +--------+  /           
  | a = 10 | /             
  | b = 3  |/              
  +--------+               
  | x = 2  |               
  +--------+               
  returns 13               

       ^             +--------+
       |             | a =    |
       |             | b =    |
       |             +--------+
       |             | x = 0  |
       |             +--------+
       |             returns 1
       |
       |                  ^             +--------+
       |                  |             | a =    |
       |                  |             | b =    |
       |                  |             +--------+
       |                  |          /  | x = -1 |
       |                  |         /   +--------+
       |                  |        /    returns 1
       |                  |       /
       |             +--------+  /
       |             | a = 4  | /
       |             | b = 3  |/
       |             +--------+
       |             | x = 1  |
       |             +--------+
       |             returns 7
       |                  
       |                  ^             +--------+
       |                  |             | a =    |
       |                  |             | b =    |
       |                  |             +--------+
       |                  |             | x = 0  |
       |                  |             +--------+
       |                  |             returns 1
       |                  |
       |                  |                  ^             +--------+
       |                  |                  |             | a =    |
       |                  |                  |             | b =    |
       |                  |                  |             +--------+
       |                  |                  |          /  | x = -1 |
       |                  |                  |         /   +--------+
       |                  |                  |        /    returns 1
       |                  |                  |       /
       |                  |             +--------+  /
       |                  |             | a = 4  | /
       |                  |             | b = 3  |/
       |                  |             +--------+
       |                  |          /  | x = 1  |
       |                  |         /   +--------+
       |                  |        /    returns 7               
       |                  |       /                    
       |                  |      /                     
       |             +--------+ /                      
       |             | a = 10 |/                       
       |             | b = 15 |                        
       |             +--------+                        
       |          /  | x = 3  |                        
       |         /   +--------+                        
       |        /    returns 25                        
       |       /                                       
  +--------+  /                                        
  | a = 16 | /                                         
  | b = 51 |/                                          
  +--------+    |                  |                  |
  | x = 5  |    |                  |                  |
  +--------+    |                  |                  |
  returns 67    |                  |                  |
                |                  |                  |
                |                  |                  |
                |                  |                  |
Brofessor有一个很好的理论方法,但他所说的有点不准确;当他说
q1(x/2)
的递归速度比
q1(x-2)
更快时,他的意思是前者将比后者更快地到达其基本情况。考虑大于5的数字。对于较大的
x
x/2
x-2
小得多。因此,
x-2
案例最终比
x/2
案例进行了更多的递归调用,因此
x-2
调用控制了堆栈的增长

例如,
q1(64)
将对
q1(x/2)
进行7次递归调用(64/2,32/2,…,1/2=0)。但是它将有更多的递归调用来调用
q1(x-2)
(64-2,62-2,60-2,…,2-2=0)


在他的画作中,如果正确的子树较大,则更为现实,因为该子树需要更长的时间才能见底。事实上,你可以在我的图表中看到这一点。如果考虑树的分支的垂直箭头和对角箭头,第一次递归调用的子树使用<代码> x/2 只有5个节点,而第一次递归调用的子树使用<代码> X-2>代码>有7个节点。几乎总是这样。

您是在询问实际的调用约定、堆栈帧是如何生成的,还是递归树的垂直高度?实际的调用约定您应该通过调试器运行此操作,以便查看每个方法调用的输出,还有你调用这个方法的次数。这个图表把事情弄清楚了。事实上,我对递归并不熟悉,我不是在谈论算法的运行时。谢谢你,递归将是令人讨厌的!当然,你会注意到,
x-2
在这里占主导地位,而不是
x/2
,所以它可能不是严格的对数。啊,我记得。。。
x = -1, q1(-1) => 1 // "q1(-1) => 1" means q1 returns 1
x = 0, q1(0) => 1 // "q1(0) => 1" means q1 returns 1

x = 1, a = 3 + q1(0) = 3 + 1 = 4
       b = 2 * q1(-1) + 1 = 2*1 + 1 = 3
       q1(1) => 7

x = 2, a = 3 + q1(1) = 3 + 7 = 10
       b = 2 * q1(0) + 1 = 2*1 + 1 = 3
       q1(2) => 13

...
                |                  |                  |
                |                  |                  |
                |                  |                  |
  +--------+    |                  |                  |
  | a =    |    |                  |                  |
  | b =    |    |                  |                  |
  +--------+    |                  |                  |
  | x = 0  |
  +--------+
  returns 1 

       ^             +--------+
       |             | a =    |
       |             | b =    |
       |             +--------+
       |          /  | x = -1 |
       |         /   +--------+
       |        /    returns 1
       |       /
  +--------+  /            
  | a = 4  | /             
  | b = 3  |/              
  +--------|               
  | x = 1  |               
  +--------+               
  returns 7                

       ^             +--------+
       |             | a =    |
       |             | b =    |
       |             +--------+
       |          /  | x = 0  |
       |         /   +--------+
       |        /    returns 1
       |       /
  +--------+  /           
  | a = 10 | /             
  | b = 3  |/              
  +--------+               
  | x = 2  |               
  +--------+               
  returns 13               

       ^             +--------+
       |             | a =    |
       |             | b =    |
       |             +--------+
       |             | x = 0  |
       |             +--------+
       |             returns 1
       |
       |                  ^             +--------+
       |                  |             | a =    |
       |                  |             | b =    |
       |                  |             +--------+
       |                  |          /  | x = -1 |
       |                  |         /   +--------+
       |                  |        /    returns 1
       |                  |       /
       |             +--------+  /
       |             | a = 4  | /
       |             | b = 3  |/
       |             +--------+
       |             | x = 1  |
       |             +--------+
       |             returns 7
       |                  
       |                  ^             +--------+
       |                  |             | a =    |
       |                  |             | b =    |
       |                  |             +--------+
       |                  |             | x = 0  |
       |                  |             +--------+
       |                  |             returns 1
       |                  |
       |                  |                  ^             +--------+
       |                  |                  |             | a =    |
       |                  |                  |             | b =    |
       |                  |                  |             +--------+
       |                  |                  |          /  | x = -1 |
       |                  |                  |         /   +--------+
       |                  |                  |        /    returns 1
       |                  |                  |       /
       |                  |             +--------+  /
       |                  |             | a = 4  | /
       |                  |             | b = 3  |/
       |                  |             +--------+
       |                  |          /  | x = 1  |
       |                  |         /   +--------+
       |                  |        /    returns 7               
       |                  |       /                    
       |                  |      /                     
       |             +--------+ /                      
       |             | a = 10 |/                       
       |             | b = 15 |                        
       |             +--------+                        
       |          /  | x = 3  |                        
       |         /   +--------+                        
       |        /    returns 25                        
       |       /                                       
  +--------+  /                                        
  | a = 16 | /                                         
  | b = 51 |/                                          
  +--------+    |                  |                  |
  | x = 5  |    |                  |                  |
  +--------+    |                  |                  |
  returns 67    |                  |                  |
                |                  |                  |
                |                  |                  |
                |                  |                  |