我想知道是否有任何正式的方式支持这一点。老实说,我不确定这是一个很好的问题,但我的目的是要知道我们是否可以在考虑递归时始终使用树作为心理模型。
更好地解释一下,我想知道“每个递归公式是否对应于树遍历?”。另外,请参阅我对Dirk答案的评论
建议的重复问题不能回答我的问题。我的问题与迭代无关。
答案 0 :(得分:2)
在解释递归时,树遍历是一个典型的例子。但是,我认为并非每个递归都对应于树遍历:
在某些语言中(lisp是其中之一),递归用于实现迭代。在那里,你还必须用递归来表达无限循环,我认为这不适合你作为递归的心理模型#34;树的概念。 (如果您想知道如何使用递归实现无限循环而不会遇到堆栈溢出:有一种称为尾调用消除的机制可以解决该问题。)
答案 1 :(得分:0)
下面是递归函数,它对整数进行操作,这是一种非树状的输入
const add = (x, y) =>
x + y
const sumTo = (x = 0) =>
x === 0
? x
: add (x, sumTo (x - 1))
console.log (sumTo ()) // 0
console.log (sumTo (1)) // 1
console.log (sumTo (2)) // 3
console.log (sumTo (4)) // 10
然而它演变了树状(递归)计算 - sumTo (4)
......
add ( 4
, add ( 3
, add ( 2
, add ( 1
, 0
)
)
)
)
// => 10
尾部递归版本具有不同的计算过程。这与Dirk Herrmann的区别是相同的(另一个答案在这里)
const add = (x, y) =>
x + y
const sumTo = (x = 0, acc = 0) =>
x === 0
? acc
: sumTo (x - 1, acc + x)
console.log (sumTo ()) // 0
console.log (sumTo (1)) // 1
console.log (sumTo (2)) // 3
console.log (sumTo (4)) // 10
在这种情况下,当尾调用消除可用时,sumTo (4)
演变迭代计算
sumTo (3, 4)
sumTo (2, 7)
sumTo (1, 9)
sumTo (0, 10)
// => 10
所以回答你的问题,不。递归过程(通过自己的名称引用自己的函数)可能会也可能不会发展递归的进程。
中讨论了这个主题