在大多数情况下,递归函数使用的内存是C中迭代函数的两倍吗?

gtlvzcf8  于 2023-10-16  发布在  其他
关注(0)|答案(2)|浏览(100)
// Recursive Implementation:
int factorialResult(int n) {
    if (n == 0) {
        return 1;
    }
    else {
        return factorialResult(n - 1) * n;
    }
}


// Iterative Implementation:
int factorialResult(int n) {
    int factorialSum = 1;
    for (int i = 1; i <= n; i++) {
        factorialSum *= i;
    }

    return factorialSum;
}

在大多数情况下,递归函数实现使用更多的内存吗?如果是这样的话,它是否是相应迭代函数实现的内存的两倍?

6gpjuf90

6gpjuf901#

在您的阶乘实现中,没有使用堆内存空间,因此在这方面,两者是相同的。它们 * 可能 * 不同的地方在于堆栈空间使用。
递归的解决方案是O(n)在堆栈空间的使用,而迭代的解决方案使用常数堆栈空间。给定足够的递归调用,递归解决方案可能会产生堆栈溢出错误。
这里有几个条件:
1.你的编译器 * 可以 * 实现尾调用优化,如果你的函数中的最后一个(或“尾”)调用只是另一个函数调用,编译器可以将其转换为一个简单的循环。
例如

int factorialResult_tailRec(int n, int acc) {
    if (n == 0) {
        return acc;
    }
    else {
        return factorialResult_tailRec(n - 1, acc * n);
    }
}

这就是所谓的factorialResult_tailRec(5, 1)
然而,这种优化不应该被指望。
1.仔细考虑您的数据类型。在遇到堆栈溢出之前,您可能会溢出int。比如,13!已经溢出了32位int,但是那些递归调用对堆栈空间没有实质性的影响。即使你将数据扩展到64位整数,21!仍然溢出并且对堆栈空间没有显著影响。

gwbalxhn

gwbalxhn2#

不是“两倍多”的内存,而是可能使用的n倍的内存。
所有这些内存都是堆栈内存。与堆内存相比,堆栈内存的分配成本更低。堆栈分配需要O(1)时间-它只是移动堆栈指针。
但它是有限的。线程通常在高端计算机上有一兆字节的堆栈,在低端设备上大约有100 KB。取决于编译器设置和操作系统架构。因此,如果调用递归factorial(500000),在溢出的结果返回给调用者之前,它会遇到一个字面上的“堆栈溢出”错误。

相关问题