可以对所有递归函数进行迭代编码吗?[关闭]


10

递归的优点是什么?

某些编程语言可以优化尾部递归,但是,总的来说,递归比常规循环消耗更多的资源。

是否可以具有某些递归函数的迭代版本?



Answers:


10

是的,您可以将递归函数编码为迭代。基本上,您需要手动维护信息,否则编译器生成的方法调用代码会处理这些信息。

换句话说,您需要一个堆栈,其中每个条目都是一个包含传递的参数和所有局部变量的结构。您始终在堆栈中最顶层的条目上工作。如果您需要自称,请创建一个新条目并将其放在堆栈顶部。完成后,拿出堆栈中最顶层的条目以显示下面的内容,并使用先前最顶层的条目提取返回值并相应地更新新的最顶层的条目。

我建议您阅读一本编译器书,以了解通常如何在机器代码中实现这一点。


我知道了。那么,递归有什么优势呢?简单?
OscarRyz 2010年

2
@OscarRyz:是的,它更加优雅。
Michael K 2010年

@OscarRyz,我描述的方式递归。只是使用本机CPU指令无法完成。手动执行操作会使您执行某些操作(例如并行化),从而严重映射到本机指令。

15

递归通常是一种比迭代更自然的看待事物的方式。例如,考虑对二叉树进行有序遍历: inorder(left); process(); inorder(right);比显式维护堆栈要简单得多。

只要您不做得太深(炸毁堆栈),资源使用的差异通常就很小。通常不用担心。尽管有例外,但是简单代码通常比手动优化代码更好。正确通常比快速好。

任何递归算法都可以表示为迭代算法,但是您可能需要保留一个显式堆栈(与隐式处理的调用堆栈相对应)。毕竟,如果您编译了一个递归函数,您将获得依赖于操作堆栈和循环遍历该函数的东西,并且这是迭代的。

尾递归函数可以轻松地转换为循环,并且不需要堆栈,但这是一种特殊情况。


8
我想说,正确永远比快速好。快速执行错误操作的代码对任何人都不好。
梅森惠勒2010年

1
但是,如果你能做到这一点错话什么真正快?
RationalGeek 2010年

1
@jkohlhepp-我可以立即解决任何问题。答案是0
自我提醒-想一个名字的

2
使用递归而不是显式堆栈会更有效-避免需要堆分配,可能的内存碎片和可能的位置问题。但是,在“正确通常比快速更好”的问题上,如果您的软件需要处理意味着代码已损坏,则堆栈溢出。通常,问题案例很容易发现-在(合理的)平衡树上进行递归很好,但在可能非常不平衡的树上或在链表上进行递归可能是C之类语言中的严重错误。 ,它可以在简单的测试中幸存下来,并且只有在真正部署时才会崩溃。
2010年

1
我想大家都知道梅森的意思,并且只是在开玩笑。当然,慢速正确的程序比快速错误的程序更有用。
Giorgio

4

递归的优点是什么?

尝试迭代解决河内塔问题。放弃后,请看一看迭代解决方案,并将其与递归解决方案进行比较。哪一个更简单?

是否可以具有某些递归函数的迭代版本?

是的,原则上。但是,对于许多问题,包括非常常见的任务(例如遍历树),与迭代解决方案相比,递归解决方案简单得多,也更优雅。


3

递归的优点是什么?

简单。如果没有尾部调用优化,那么它当然会占用更多资源(堆栈),但是,例如,如何deltree在Java中实现而无需递归呢?delete()唯一的问题是,只有在目录为空时才可以删除目录。这是递归的:

deltree(File fileOrDirectory) {
    if (fileOrDirectory.isDirectory()) {
        for (File subFileOrDirectory : fileOrDirectory.listFiles()) {
            deltree(subFileOrDirectory);
        }
    }
    fileOrDirectory.delete();
}

1
带有堆栈,如其他答案所述。
妮可,2010年

是的,但是那有多简单?-)
Joonas Pulakka 2010年

哦,递归绝对更好。我以为你是说不可能。
妮可

0

我相信递归是程序员必须使用的那些工具之一。通过递归,您可以“思考”您的算法并按照您的想法解决它们。但是,我必须警告您,每个人都在谈论递归是多么的漂亮,给代码带来了多少简化,关于我还有几句话要说:

  1. 首先,思考算法的“递归方式”并不容易。建立像阶乘(n!)之类的函数或类似Hanoi Towers之类的函数只是冰山一角,而到达底部则需要很长的时间。
  2. 不要以为递归只会在代码中带来简单性,有时候,迭代的方式很难看而且凌乱,但是却具有成本效益(请看一下斐波纳契问题的递归解决方案)

牢记这些,学习递归!它很有趣,很复杂,会砸碎您的大脑!但是您会发现自己喜欢它。

祝你好运!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.