为什么禁止尾递归 学习了解递归和尾递归的区别?
递归是在运行过程中调用自身。递归的条件如下:
学习了解递归和尾递归的区别?
如果递归级别太多,则会出现堆栈溢出异常,因为每次调用都会生成一个新的堆栈帧,用于保留当前函数的状态值。如果不需要保存状态值,则可以重用堆栈帧而不会导致堆栈溢出。
以n的阶乘为例:
正常递归:
如果n=3,则每一步都需要保留n值和下一个函数的返回值,因此每次调用都需要创建一个新的堆栈帧
尾部递归:
如果n=3,则每次调用都可以重用堆栈帧,因为不需要保存状态值。
因此,当递归在当前堆栈帧执行后完成时,它不需要保留当前堆栈帧,但根据当前堆栈帧的结果,它可以在进入下一个堆栈帧时优化为尾部递归。通常,尾部递归需要满足递归调用是函数体中最后执行的语句。例如,在factorial示例中,要执行的最后一条语句是直接调用factorial(n-1,n*result),而不是表达式n*factorial(n-1)。如果是表达式,则需要堆栈帧来保留N和阶乘(N-1)的结果。
尾递归究竟是好是坏?
递归算法是一种直接或间接调用自身的算法。在计算机程序设计中,递归算法对于解决一大类问题是非常有效的。它往往使算法的描述简洁易懂。递归是在过程或函数中调用自身。在使用递归策略时,必须有一个显式的递归结束条件,称为递归退出。递归算法通常非常简单,但效率较低。因此,不建议使用递归算法来设计程序。在递归调用过程中,系统打开一个栈来存储每一层的返回点和局部数量。太多的递归很容易导致堆栈溢出。
程序的递归算法与非递归有什么区别?
递归和迭代都是循环类型。简单地说,递归就是反复调用函数本身来实现循环。迭代是由函数中的某些代码实现的循环。迭代与普通循环的区别在于,循环代码中参与运算的变量也是保存结果的变量,当前保存的结果是下一次循环计算的初始值。在递归循环中,当满足终止条件时,循环将逐层返回。迭代使用计数器结束循环。当然,在许多情况下,各种循环是混合的,这取决于具体的需要。递归示例,例如,给定一个整数数组,使用半查询返回数组中指定值的索引,假设数组已排序。为了便于描述,假设所有的元素都是正数,数组的长度是2的整数倍。半查询是一种查询,它比遍历所有元素快得多。迭代的经典例子是实数的累加,例如计算从1到100的所有实数之和。
递归与迭代的区别?
尾部递归:程序中只有一个递归语句,它位于末尾。单向递归:指程序中的递归语句,在程序运行之前已经完成,如斐波那契数列。这样做的共同特点是在转换非递归时不必保存分支路由
如果这样的CFG离开了递归,递归下降法和语法分析中的LL(1)就不能处理它,因为程序会陷入递归,不能前进。Cfga-> BA“a”-> BA“| e与前面的表达式相同,但所有语法的第一项是终止符,它消除了左递归。有消除左递归的算法,一般编译原理书中会介绍,不是很复杂。
版权声明:本文内容由互联网用户自发贡献,本站不承担相关法律责任.如有侵权/违法内容,本站将立刻删除。