计算机语言 递归调用有什么好处一般什么情况下要递归?
递归调用有什么好处一般什么情况下要递归?递归的基本思想是“调用你自己”。使用递归的方法是直接或间接地调用自己。其实递归方法体现了“类比”和“同步重复”的思想。它可以用简单的程序解决一些复杂的计算问题,
递归调用有什么好处一般什么情况下要递归?
递归的基本思想是“调用你自己”。使用递归的方法是直接或间接地调用自己。
其实递归方法体现了“类比”和“同步重复”的思想。它可以用简单的程序解决一些复杂的计算问题,但计算量很大。还有一些数据结构,如二叉树,具有固有的递归特性;另外还有一种问题,虽然没有明显的递归结构,但由于其普遍性,用递归程序编写程序比其它方法更容易,如八皇后问题、河内塔问题等对于递归程序,我们应该学会用递归来解决问题。无论是直接递归还是间接递归,都需要在当前层调用下一层时实现参数传递,获取下一层返回的结果,并通过调用上一层返回当前层的结果。对于各层调用的现场存储和恢复,由程序自动实现,无需人工干预。因此,在递归程序的设计中,关键是找出调用所需的参数、返回的结果以及递归调用结束的条件。例如,在阶乘函数fact(n)中,每层需要传递一个自然数n并返回n*fact(n-1)。递归调用结束的条件是n=0。据此,编写相应的程序很方便
如果递归级别太多,就会导致堆栈溢出异常,因为每次调用都会生成一个新的堆栈帧,并使用这个堆栈帧来保留当前函数的状态值。如果不需要保存状态值,则可以重用堆栈帧而不会导致堆栈溢出。
以n的阶乘为例:
正常递归:
如果n=3,则每一步都需要保留n值和下一个函数的返回值,因此每次调用都需要创建一个新的堆栈帧
尾部递归:
如果n=3,则每次调用都可以重用堆栈帧,因为不需要保存状态值。
因此,当递归在当前堆栈帧执行后完成时,它不需要保留当前堆栈帧,但根据当前堆栈帧的结果,它可以在进入下一个堆栈帧时优化为尾部递归。通常,尾部递归需要满足递归调用是函数体中最后执行的语句。例如,在factorial示例中,要执行的最后一条语句是直接调用factorial(n-1,n*result),而不是表达式n*factorial(n-1)。如果是表达式,则需要堆栈帧来保留N和阶乘(N-1)的结果。