迭代和递归有什么区别
What is the difference between iteration and recursion?
iteration
和recursion
有什么区别,为什么/什么时候更好:
while (true) {
// Iterating
}
和
private void recursion() {
if (true)
recursion(); // Recursing
return;
}
我看到很多recursive
实现,而它可以在一个简单的循环中轻松完成。
递归和同一算法的迭代版本之间有两个主要区别。
首先,有时理解递归算法比理解迭代算法要好得多(至少如果你是经验丰富的程序员)所以它确实提高了表现力,在某些情况下还增加了可读性(在其他情况下也可能导致完全相反的情况)
Expresivity 在编程语言中是一件大事,能够在 5 行而不是 20 行中编写相同的代码是一件大事。
不利的一面是,它会降低代码的性能。递归函数必须将函数记录保存在内存中,并从一个内存地址跳转到另一个内存地址,以调用以传递参数和返回值。这使得它们的性能非常糟糕。
概括:
迭代算法 = 性能快,但难以编写(有时也难以阅读)
递归算法=编写速度快,但性能不佳(有时也更容易理解)
举个例子:
public static long fib(long n) {
if (n <= 1) return n;
else return fib(n-1) + fib(n-2);
}
与
if ((n == 1) || (n == 2)) {
return 1;
} else {
long prev = 1, current = 1, next = 0;
for (long i = 3; i <= n; i++) {
next = prev + current;
prev = current;
current = next;
}
return next;
}
源:
http://www.csd.uwo.ca/Courses/CS1027a/code/FibonacciDemo.java
递归和迭代之间的主要区别在于内存使用。
对于每个递归调用,堆栈帧上都需要空间,从而导致内存开销。
我举个例子。想象一下,在一种情况下,您忘记为递归函数编写基本情况,从而导致无休止的递归调用,而在另一种情况下,您编写了一个无限循环。
由于每个递归函数都会分配新的内存空间,因此在第一种情况下,您的代码将给出堆栈溢出异常,但在第二种情况下,它将永远保持运行。
因此,使迭代代码比使用递归更易于理解更好。
它们是做同一件事的不同方式。所有递归实现都可以通过一个(或多个)循环来完成,反之亦然。它更多的是关于它背后的逻辑,一种思考它的方式。阶乘虽然不是最好的例子,但却是n * (n-1)!
,因此递归使用它很有意义。
递归和迭代是思考解决方案的不同方式。要全面解释这种差异是困难的。在您的示例代码中,您显示了差异。递归函数是调用自身的函数,而迭代函数是循环通过某些代码块的函数。以下是一些文章,可帮助您更好地理解它们:递归维基
迭代维基
代码项目所以#1
所以#2
它们可以互换使用来解决不同的问题。从本质上讲,您可以迭代地编写递归函数,反之亦然。
迭代可能会提高程序的性能。而递归可能会给出更直观和优雅的结果。您可以根据自己的喜好选择其中之一!
递归函数通过调用自己的过程直到满足条件,而迭代使用循环控制结构(例如 while、do while、for)来重复一段代码,直到满足某个条件。
递归示例:
int rec_func(int u, int k) {
if (k == 0)
return u;
return rec_func(u * k, k - 1);
}
迭代示例:
int ite_func(int u, int k) {
while (k != 0) {
u = u * k;
k = k - 1;
}
return u;
}
IMO之间唯一真正的区别是编译差异。
理论上,您始终可以在迭代和递归之间切换。但是,至少在 C/C++/C#/Java 的情况下,编译器会为您提供一些支持,这可能会使解决方案更加优雅,尤其是当您之前不知道循环数时。
最好的示例是列出文件夹中的所有文件及其后代。如果有多个子文件夹包含子文件夹,则在迭代模式下,通常需要一个堆栈来保存需要分析的所有文件夹。在递归方法的情况下,编译器已经提供了堆栈,并且解决方案更加优雅。
递归和迭代之间的差异
递归
- 递归函数 – 是部分由自身定义的函数
- 递归使用选择结构
- 如果递归步骤没有以收敛于某些条件(基本情况)的方式减少问题,则会发生无限递归
- 当识别基本情况时,递归终止
- 由于维护堆栈的开销,递归通常比迭代慢
- 递归比迭代使用更多的内存
- 无限递归会使系统崩溃
- 递归使代码更小
迭 代
- 迭代指令 – 是基于循环的过程重复
- 迭代使用重复结构
- 如果循环条件测试永远不会变为 false,则迭代时会发生无限循环
- 循环条件失败时迭代终止
- 迭代不使用堆栈,因此它比递归更快
- 迭代消耗更少的内存
- 无限循环反复使用 CPU 周期
- 迭代使代码更长
数据取自此处。
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 在 .h 文件中的类中声明静态变量和在.cpp文件中声明"global"变量有什么区别
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 返回常量对象引用 (getter) 和仅返回字符串有什么区别?
- Qt:remove() 和 rmdir() 有什么区别
- 这 4 个 lambda 表达式之间有什么区别?
- 将向量作为类>(值)<向量启动和向量<类>[值]有什么区别
- typedef 枚举和枚举类有什么区别?
- &C::c 和 &(C::c) 有什么区别?
- ascii 和 unicode 在处理级别有什么区别吗?
- C 中的常量限定符和 C++ 中的常量限定符有什么区别?
- "ABC" 和 "ABC" ) 在C++中有什么区别?
- 空指针常量 (nullptr)、空指针值和空成员指针值之间有什么区别?
- 引用捕获和在 lambda 中通过引用发送参数有什么区别 (C++)
- 两种访问I2C总线的方法有什么区别?
- 两种模板示例有什么区别?
- 这两种C++语法之间有什么区别?
- lua 5.0.2 模块和 5.3.5 有什么区别?
- C++中"typedef"、"using"、"namespace"和"using namespace"有什么区别?
- std::enable_if 和 std::enable_if_t 有什么区别?