2017-05-24 56 views
-2

我最近了解到尾递归作为一种递归方式,当你给它一个太大的数字来处理时,它不会崩溃。我意识到我可以很容易地将一个尾递归作为一个while循环来重写,并且它基本上完全相同,这导致我想知道 - 当你用普通循环做所有事情时,有没有用于递归?递归有什么用处吗?

是的,递归代码看起来更小,更容易理解,但它也有可能完全崩溃,而简单的循环无法崩溃做同样的任务。

+0

欢迎来到StackOverflow。请阅读并遵守帮助文档中的发布准则。 [在主题](http://stackoverflow.com/help/on-topic)和[如何提问](http://stackoverflow.com/help/how-to-ask)适用于此处。 这个问题在Stack Overflow和Internet上已经有了很多答案。 – Prune

+2

有没有用于循环?递归可以做一切循环都可以。一个简单的循环会因索引超出范围或整数溢出而崩溃,但是您知道,程序员不应该为确保其代码不会崩溃负责! – MrZander

+0

@Prune我没有发现他们中的任何一个对我有帮助 – umnikos

回答

0

我要例如Haskell language,它是纯功能

在Haskell每个功能是在数学意义上 (即,“纯”)的功能。即使是副作用的IO操作也不过是纯代码生成的内容的描述。没有 语句或指令,只有表达式不能变异 变量(本地或全局),也不像访问状态像时间或随机 号码。

所以,在Haskell递归函数是尾递归如果 递归调用的最终结果是函数本身的最终结果。如果必须进一步处理递归调用的结果(例如,通过向其添加 1或将另一个元素添加到它的开头),则不是尾递归的 。 (see here

另一方面,在许多编程语言中,调用一个函数使用堆栈空间,所以一个尾递归函数可以构建一个大堆的自身调用,这会浪费内存。由于在尾调用中,包含函数即将返回,它的环境实际上可以被丢弃,并且递归调用可以在不创建新的栈帧的情况下进入。这个技巧被称为尾部呼叫消除或尾部呼叫优化,并允许尾部递归功能无限期地重复发生。

+0

可能有重复的问题。我目前正在学习lisp,它有标准循环和尾递归优化。我试图找到一个理由,当一个普通的循环完成相同的工作而不声明函数时使用尾递归。 – umnikos

+1

您是否尝试过使用循环解决河内塔? – Nykros

+0

这是一个梦幻般的例子@Nykros,在很多方面是更简单的阅读和理解尾递归,有时也更快 –