使用两个递归了解递归概念

时间:2014-10-28 03:57:38

标签: ruby algorithm recursion stack

我正在尝试解决合并排序,我迷失在递归概念中。所以为了让自己更好地理解,我提出了一个小例子。

对于下面的程序使用n= 2,我得到答案0,1,2我完全理解使用堆栈的概念,并在完成递归后逐个通过puts n返回堆栈的值。

 def one(n)
  if n < 0
   return
  end
  one(n-1)
  puts n
 end

但是当我尝试使用下面的另一个递归时,我完全迷失了为什么以及如何回答0,0,1,0,0,1,2。谁能简单解释一下呢?

 def one(n)
  if n < 0
   return
  end
  one(n-1)
  one(n-1)
  puts n
 end

请添加足够的说明,了解这两种递归是如何协同工作的。

2 个答案:

答案 0 :(得分:1)

one(n)两次调用one(n-1),然后调用puts n,如下所示:

one(2) -> one(1) -> one(0) -> one(-1) 
                           \> one(-1) 
                           \> puts 0  
                 \> one(0) -> one(-1) 
                           \> one(-1) 
                           \> puts 0
                 \> puts 1
       \> one(1) -> one(0) -> one(-1) 
                           \> one(-1) 
                           \> puts 0
                 \> one(0) -> one(-1) 
                           \> one(-1) 
                           \> puts 0
                 \> puts 1
       \> puts 2

上述图片中的功能如下所示:one(2)调用one(1),调用one(0),然后调用one(-1),此one(-1)返回,一(0)个调用第二个one(-1),第二个one(-1)返回,one(0)调用puts 0,然后one(0)返回,返回第二个{{1}等等。

答案 1 :(得分:1)

以下是第二次递归的图示。行指示操作的顺序;列递归级别:

n = 2
return if n < 0
one(1) ->        n=1
                 return if n < 0
                 one(0) ->        n=0
                                  return if n < 0
                                  one(-1) ->       n=-1
                                                   return if n < 0
                                                   <-

                                  one(-1) ->       n=-1
                                                   return if n < 0
                                                   <-
                                  puts 0
                                  <-

                 one(0) ->        n=0
                                  return if n < 0
                                  one(-1) ->       n=-1
                                                   return if n < 0
                                                   <-

                                  one(-1) ->       n=-1
                                                   return if n < 0
                                                   <-
                                  puts 0
                                  <-
                 puts 1
                 <-

  one(1) ->      n=1
                 << same as above, resulting in `puts 0`, `puts 0`, `puts 1` >>
                 <-
  puts 2

将每个递归级别(列)视为一个单独的方法。它执行一些操作然后调用另一个方法。在这种情况下,它自称,但你不应该这样想;只是把它想象成一种方法。最终该方法返回,可能带有值(但不是这里),并且该方法以正常方式继续到下一个语句(行)。最终它返回到调用它的方法。这恰好是同一种方法,但同样,将其视为一种方法。

通过对比,这是您第一次递归时发生的事情:

n = 2
return if n < 0
one(1) ->        n=1
                 return if n < 0
                 one(0) ->        n=0
                                  return if n < 0
                                  one(-1) ->       n=-1
                                                   return if n < 0
                                                   <-
                                  puts 0
                                  <-
                 puts 1
                 <-
puts 2