递归有哪些优点和缺点?

时间:2011-03-09 18:55:35

标签: recursion

关于在排序算法中使用非递归方法的递归,或者就此而言,任何算法的优缺点是什么?

10 个答案:

答案 0 :(得分:28)

在大多数情况下,递归速度较慢,并且占用了更多的堆栈。递归的主要优点是,对于像树遍历这样的问题,它使算法更容易或更“优雅”。 查看一些比较:

link

答案 1 :(得分:13)

递归意味着函数重复调用

它使用系统堆栈来完成它的任务。由于堆栈使用LIFO方法 当一个函数被调用时,被控制被移动到定义函数的地方,该函数被存储在具有某个地址的存储器中,该地址存储在堆栈中

其次,它减少了程序的时间复杂度。

虽然有点偏离主题,但有点相关。必读。 :Recursion vs Iteration

答案 2 :(得分:12)

所有算法都可以递归定义。这使得可视化和证明更加容易。

某些算法(例如Ackermann Function)无法(轻松)迭代指定。

如果无法执行tail call optimization,递归实现将使用比循环更多的内存。虽然迭代可能比无法优化的递归函数使用更少的内存,但它在表达能力方面存在一些限制。

答案 3 :(得分:4)

我个人更喜欢使用Iterative而不是递归函数。特别是如果你的函数具有复杂/重的逻辑并且迭代次数很大。这是因为每个递归调用调用堆栈都会增加。如果操作太大并且还会减慢进程,它可能会使堆栈崩溃。

答案 4 :(得分:4)

开始:

优点:

  • 这是实现可变数量的嵌套循环的独特方式(以及实现大量常量嵌套循环的唯一优雅方法)。

缺点:

  • 递归方法在处理大集时经常会抛出StackOverflowException。递归循环没有这个问题。

答案 5 :(得分:4)

使用递归实现的任何算法也可以使用迭代实现。

为什么使用递归

  1. 由于维护堆栈的开销,它通常会变慢。
  2. 它通常会为堆栈使用更多内存。
  3. 为什么 使用递归

    1. 递归增加了清晰度并且(有时)减少了编写和调试代码所需的时间(但不一定会减少空间要求或执行速度)。
    2. 减少时间复杂度。
    3. 更好地解决基于树结构的问题。
    4. 例如,使用递归而不是迭代,更容易解决河内塔问题。

答案 6 :(得分:0)

表现力

大多数问题通过递归来自然表达,例如Fibonacci,Merge排序和快速排序。在这方面,代码是为人而不是机器编写的。

不变性

迭代解决方案通常依赖于不同的临时变量,这使得代码难以阅读。这可以通过递归来避免。

效果

递归不是堆栈友好的。如果没有很好地设计递归或者不支持尾部优化,则堆栈可能会溢出。

答案 7 :(得分:0)

有些情况会出现你必须放弃递归似乎对你有利的问题的递归,这是因为对于递归必须发生数千次的问题,这会导致堆栈溢出错误,即使你的代码没有陷入无限递归。大多数编程语言限制你进行大量的堆栈调用,因此如果你的递归超出了这个限制,那么你可能会考虑不使用递归。

答案 8 :(得分:0)

在以下情况下,我们应该使用递归:

  • 当我们不知道有限的迭代次数时,例如,我们的功能退出条件是基于动态编程(记忆)的
  • 当我们需要按相反的顺序执行操作时。这意味着我们要先处理最后一个元素,然后再处理n-1,n-2,依此类推,直到第一个元素

递归将保存多个遍历。如果我们可以像这样划分堆栈分配,它将很有用:

int N = 10;
int output = process(N) + process(N/2);
public void process(int n) {
    if (n==N/2 + 1 || n==1) {
       return 1;
    }

    return process(n-1) + process(n-2);
}

在这种情况下,在任何给定时间仅分配一半堆栈。

答案 9 :(得分:0)

递归的名声很差,我总是惊讶于有多少开发人员甚至不会接触递归,因为有人告诉他们这是邪恶的化身。

我通过反复试验了解到如果做得正确递归可以是迭代某事的最快方法之一,它不是一个固定的规则,每个语言/编译器/引擎有它自己的怪癖,所以里程会有所不同。

在 javascript 中,我可以通过引入递归来可靠地加速几乎任何迭代过程,并增加了减少副作用并使代码更加清晰简洁和可重用的好处。还专业提示它可能解决堆栈溢出问题(并且不禁用警告)。

我个人的利弊:

优点:

- Reduces side effects.
- Makes code more concise and easier to reason about.
- Reduces system resource usage and performs better than the traditional for loop.

缺点:

- Can lead to stack overflow.
- More complicated to setup than a traditional for loop.

里程会因语言/编译器/引擎而异。