什么是递归?它是如何工作的?

时间:2011-06-20 21:53:59

标签: ruby recursion

有人可以解释究竟什么是递归(以及它在Ruby中是如何工作的,如果这不是太多要求)。我遇到了一个依赖递归的冗长代码片段,它使我感到困惑(我现在丢失它,并不完全相关)。

4 个答案:

答案 0 :(得分:61)

递归函数/方法调用自身。对于要终止的递归算法,您需要一个基本情况(例如,函数递归调用自身的条件),并且还需要确保在每次递归调用中更接近该基本情况。让我们看一个非常简单的例子:

def countdown(n)
  return if n.zero? # base case
  puts n
  countdown(n-1)    # getting closer to base case 
end               

countdown(5)
5
4
3
2
1

一些问题可以通过递归非常优雅地表达,例如,许多数学函数以递归方式描述。

答案 1 :(得分:33)

要理解递归,首先需要了解递归。

现在,严肃地说,递归函数是一个自我调用的函数。这种构建体的一个典型例子是斐波那契序列:

def fib(n)
  return n if (0..1).include? n
  fib(n-1) + fib(n-2) if n > 1
end

使用递归函数可以提供强大的功能,但也会带来很多的责任感(双关语)并且会带来一些风险。例如,如果你的递归太大,你可能最终会出现堆栈溢出(我正在滚动): - )

答案 2 :(得分:4)

Ruby on Rails 示例:

递归会生成父母父母的数组

<强> A / M / document.rb

class Document < ActiveRecord::Base

  belongs_to :parent, class_name: 'Document'

  def self.get_ancestors(who)
    @tree ||= []
    # @tree is instance variable of Document class object not document instance object
    # so: Document.get_instance_variable('@tree')

    if who.parent.nil?
      return @tree
    else
      @tree << who.parent
      get_ancestors(who.parent)
    end
  end

  def ancestors
    @ancestors ||= Document.get_ancestors(self)
  end

end

控制台

d = Document.last
d.ancestors.collect(&:id)
# => [570, 569, 568] 

https://gist.github.com/equivalent/5063770

答案 3 :(得分:2)

通常,递归是关于调用自身的方法,但也许你遇到的是递归结构,即引用自身的对象。 Ruby 1.9处理得非常好:

h = {foo: 42, bar: 666}
parent = {child: {foo: 42, bar: 666}}
h[:parent] = parent
h.inspect # => {:foo=>42, :bar=>666, :parent=>{:child=>{...}}}

x = []
y = [x]
x << y
x.inspect # => [[[...]]]
x == [x]  # => true

我发现最后一行非常邪恶;关于这类几年前递归结构比较的问题,我blogged