我在思考具有递归算法的真正目的是什么。 我们都知道递归算法是紧凑的,并且在某些方面是可以理解的。但是,递归的最大缺点是递归算法在运行时需要大量的系统资源。这导致了一个结果,即递归算法应该只在一个非常“简单的数据”上运行(我不确定我是否使用了正确的词)。
E.g:我写了一个算法,用递归算法计算某个矩阵的格子路径数。该算法适用于小矩阵大小,但是当处理矩阵大小时> 20,计算机完成任务需要永远。所以我必须使用常规方法重写我的算法。
有人可以向我解释使用递归算法的目的吗?因为它对系统资源的使用不是很有效,并且可以通过常规方法完全重写(我知道有时可能很难重写递归算法)。
答案 0 :(得分:3)
实际上,在这种情况下,一个人的垃圾是另一个人的财富。但是为了备份,让我们考虑一下你对系统资源的巨大影响":忽略缓存和流水线的问题,递归算法使用的资源"无形的"是用于进行递归调用的系统堆栈空间:当前指令指针被推送到堆栈以及递归函数的所有参数。此外,递归过程的局部变量是在堆栈上创建的,尽管在任何函数中都是这种情况,但局部变量占用的内存乘以递归深度。尽管如此,这并不一定等于"巨大的。"
递归方法的优点(除了你提到的那些)是......等待它...你可以使用系统堆栈作为另一种数据结构。考虑用于探索二叉树的递归算法:通过将节点参数传递给递归函数,您实际上是在维护一个数据结构(即堆栈),您需要在该数据结构中明确维护非递归方法,不同之处在于,在递归函数中,您不必明确地声明和维护堆栈。所以唯一的额外"浪费" recources是堆栈框架中你需要的任何东西,加上堆栈上指令指针的大小*递归的深度。对于一个简单易懂的算法,通过不必声明一个显式数据结构来存储节点指针就可以简化这个算法,这是一个很小的代价。
请记住,对于许多递归函数,递归方法不涉及实际递归:如果递归调用是递归函数中的最后一个调用,并且调用函数本身返回递归调用的结果,然后tail call optimization(在许多编译器上可用)将生成非递归代码。