一种算法, 用于计算机编程技术.
尾递归是针对传统的递归算法而言的, 传统的递归算法在很多时候被视为洪水猛兽. 它的名声狼籍, 好像永远和低效联系在一起.
尾递归就是从最后开始计算, 每递归一次就算出相应的结果, 也就是说, 函数调用出现在调用者函数的尾部, 因为是尾部, 所以根本没有必要去保存任何局部变量. 直接让被调用的函数返回时越过调用者, 返回到调用者的调用者去.
以下是具体实例:
线性递归:
long Rescuvie(long n) {
return(n == 1) ? 1 : n * Rescuvie(n - 1);
}
尾递归:
long TailRescuvie(long n, long a) {
return(n == 1) ? a : TailRescuvie(n - 1, a * n);
}
long TailRescuvie(long n) {//封装用的
return(n == 0) ? 1 : TailRescuvie(n, 1);
}
当n = 5时
对于线性递归, 他的递归过程如下:
Rescuvie(5)
{5 * Rescuvie(4)}
{5 * {4 * Rescuvie(3)}}
{5 * {4 * {3 * Rescuvie(2)}}}
{5 * {4 * {3 * {2 * Rescuvie(1)}}}}
{5 * {4 * {3 * {2 * 1}}}}
{5 * {4 * {3 * 2}}}
{5 * {4 * 6}}
{5 * 24}
120
对于尾递归, 他的递归过程如下:
TailRescuvie(5)
TailRescuvie(5, 1)
TailRescuvie(4, 5)
TailRescuvie(3, 20)
TailRescuvie(2, 60)
TailRescuvie(1, 120)
120
很容易看出, 普通的线性递归比尾递归更加消耗资源, 在实现上说, 每次重复的过程
调用都使得调用链条不断加长. 系统不得不使用栈进行数据保存和恢复.而尾递归就
不存在这样的问题, 因为他的状态完全由n和a保存.
//
首先:尾递归是线性递归的子集,属于线性递归。具体概念请参阅各大高校出版的书籍。作者把概念搞错了
其次,上文所举的第二个例子中在TailRescuvie(n-1, 1)没有计算出来之前,是不能return的。也就是说递归过程和第一个例子是差不多的,根本没有节约资源,甚至更浪费。
其实,编译器会很容易的对尾递归使用跳转语句进行优化,其实是可以return的。
分享到:
相关推荐
前端大厂最新面试题-tail_recursion 本文主要讲述了递归和尾递归的概念、实现和应用场景。递归是一种函数调用自身的方法,可以将一个大型复杂的问题分解成一个与原问题相似的规模较小的问题来求解。递归需要有边界...
《Python库tail_recursion-1.1.1-py3-none-any.whl详解》 在Python编程领域,库是开发者的重要工具,它们提供了丰富的功能,让编写代码变得更加高效和便捷。今天我们要关注的是一个名为"tail_recursion"的库,其...
例子倒数至零一个简单的尾递归函数,倒数为零:前后static void count( int n) { if (n == 0 ) { return ; } count(n - 1 ); } static void count( int n) { while ( true ) { if (n == 0 ) { return ; } n = n - 1 ...
在编程语言中,尾递归和trampolining是两种优化技术,主要用于处理深度递归,从而避免调用栈溢出的问题。C#作为一种高级的面向对象编程语言,虽然默认不支持尾递归优化,但我们可以利用trampolining来模拟这种优化。...
尾递归(Tail Recursion)是一种特殊的递归形式,它是递归概念的一个子集,主要用于优化递归算法。普通递归在执行过程中会不断积累调用栈,随着递归深度的增加,内存消耗也会急剧增大,可能导致栈溢出错误。而尾递归...
但Python标准解释器并未对尾递归进行优化,所以尾递归在Python中的效果并不明显。 3. **循环**: 循环是最有效的方法,如 `Fib_circle` 函数所示。通过循环,我们可以避免递归带来的额外开销,只需线性时间复杂度...
此外,递归在Java中也有一些优化技巧,例如尾递归(Tail Recursion),这是一种特殊形式的递归,在递归调用的最后返回结果,编译器或解释器有可能优化这种递归,使其等效于迭代,从而提高性能并避免栈溢出。...
为了避免这种情况,可以考虑使用尾递归(Tail Recursion)、记忆化(Memoization)或迭代(Iteration)等优化方法。 尾递归是指在递归调用的最后返回结果,这样编译器或解释器有可能优化掉多余的栈帧,减少内存消耗...
再者,Scala中的惰性求值(Lazy Evaluation)和尾递归(Tail Recursion)是优化性能的重要手段。惰性求值可以延迟计算直到真正需要,减少不必要的计算开销;尾递归则可以避免递归深度过大导致的栈溢出问题,通过优化...
在实际开发中,尾调用优化通常和尾递归(Tail Recursion)一起讨论。尾递归是指函数的最后一步调用自身,并且返回值是调用的结果。尾递归是尾调用的一个特例,也是函数式编程语言中常见的优化技术。 例如,以下是一...
- **尾递归(Tail Recursion)**:在CPS中,如果函数的最后一步是调用另一个函数,并且没有其他操作,那么这就是尾递归。这种情况下,编译器可以优化掉栈帧,避免无限递归导致的栈溢出。 - **柯里化(Currying)**:...
为了优化递归,可以考虑使用尾递归(tail recursion),即递归调用成为函数体的最后一个操作,编译器可以优化为迭代形式。另外,使用记忆化技术(memoization)可以避免重复计算,提高效率。 总结起来,C++中的递归...
2. **Tail Recursion Exception**:Python本身并不支持原生的尾递归优化。然而,可以通过一些技巧来模拟实现,例如使用异常来传递控制流。在提供的代码示例中,定义了一个`TailRecurseException`类,用于在检测到尾...
10. **尾递归(Tail Recursion)**:优化递归函数,使其在结束时只调用自身,而不是进行其他操作。虽然JavaScript引擎并未内置尾递归优化,但开发者可以通过手动实现,Underscore.js并不直接支持尾递归优化,但理解其...
闭包的这种特性使其成为实现函数式编程概念如柯里化(Currying)和尾递归(Tail Recursion)的理想工具。柯里化允许我们将一个多参数的函数转换为一系列单参数函数,从而更容易进行组合和复用。尾递归优化则是Swift...
8. **尾递归(Tail Recursion)**:Swift优化了尾递归,使得无限递归变得更加高效。尾递归是指在递归调用中,函数的最后一步是调用自身,并且调用是表达式的最后一部分。 9. **函数式数据结构(Functional Data ...
4. **尾递归(Tail Recursion)**:优化递归调用,确保在内存使用上更有效率。 5. **函数作为值返回**:函数可以像其他值一样被赋值、传递和存储,增强了函数式编程的能力。 6. **一流的计算连续传值调用(Passing...
除此之外,书中还可能涵盖了其他函数式编程概念,如柯里化(Currying)、高阶函数(Higher-Order Functions)、尾递归(Tail Recursion)优化、闭包(Closures)的使用,以及如何通过函数式编程风格来实现常见的设计...
例如,典型的尾递归(Tail Recursion)是递归的一种优化形式,在这种情况下,递归调用是函数体的最后一个操作。Clojure的编译器可以识别并优化尾递归,使其在有限的堆栈空间内执行,避免了无限递归导致的堆栈溢出...