递归和迭代的解释可以搜到很多,不论是程序举例还是比喻举例等等,解释的方法也是五花八门,但每个人都应该有一个自己的例子(哪怕是借用别人的变成自己的),这样才能记得住。
举个栗子:现在给定一个烧水的方法:从0度烧到100度,再给三个盛满水的水壶,水壶里水的温度分别是0度、50度和80度。
要求:分别用递归和迭代的思维方式烧开三壶水。
递归:实际上,递归就是先给定一个函数(方法)F,然后在F的函数体中不断的调用F自身或通过一连串的函数调用,最终间接调用F。
所以,第一壶0度水,我们直接烧到100度;
第二壶50度水,因为是递归思想,我们只知道方法从0烧到100度,所以我们要先把50度的水降温到0度,再从0烧到100度;
第三壶水,同第二壶一样,先降温到0度,再从0烧到100度。
迭代:迭代常与循环配合使用,是在程序(循环)中先给定初始条件和终止条件,然后,对一组指令(或一定步骤)不断的重复。
所以,第一壶水的初始条件为0度,那么我们就重复加热步骤,把水从0烧到100度,共需加热100度。
第二壶水的初始条件为50度,那么我们就重复加热步骤,把水从50烧到100度,共需加热50度。
第三壶水的初始条件为80度,那么我们就重复加热步骤,把水从80烧到100度,共需加热20度。
应用举例,经典的斐波那契数列:
/*
* 通过递归和迭代两种方法求斐波那契数列。
* 0,1,1,2,3,5,8,13,21,34,55....
* */
import java.util.*;
public class Fibonacci {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();//用递归方法
int m = in.nextInt();//用迭代方法
int k = in.nextInt();//改进迭代方法
in.close();
//用迭代方法输出斐波那契数列
for(int i=0;i<=n;i++){
if(i!=n)
System.out.print(Fibonacci1(i)+",");
else
System.out.println(Fibonacci1(i));
}
//用迭代方法输出斐波那契数列
Fibonacci2(m);
System.out.println();
//用优化的迭代方法输出斐波那契数列
for(int i=0;i<=k;i++){
if(i!=k)
System.out.print(Fibonacci3(i)+"、");
else
System.out.print(Fibonacci3(i));
}
}
//递归
static int Fibonacci1(int n){
if(n<0)
return 0;
if(n<=1)
return n;
else
return(Fibonacci1(n-1)+Fibonacci1(n-2));
}
//迭代
static void Fibonacci2(int m){
int []arr = new int[m+1];
arr[0] = 0;
arr[1] = 1;
for(int i=0;i<=m;i++)
{
if(i<2)
System.out.print(arr[i]+" ");
else{
arr[i] = arr[i-1]+arr[i-2];
System.out.print(arr[i]+" ");
}
}
}
//优化迭代算法
static int Fibonacci3(int m){
int F=0,Fa,Fb;
Fa = 0;
Fb = 1;
for(int i=0;i<=m;i++)
{
if(i==0)
F = Fa;
else if(i==1)
F = Fb;
else{
F = Fa+Fb;
Fa = Fb;
Fb = F;
}
}
return F;
}
}
/*6 6 6
0,1,1,2,3,5,8
0 1 1 2 3 5 8
0、1、1、2、3、5、8
*/
递归的优缺点:优点: 把规模大的问题转化为规模小的相似的子问题来解决,当获得最简单的情况后,逐步返回,依次得到复杂问题的解。
缺点:因为要不断的调用,再一层层回归所以,需要用堆栈记录存储每一次递归的结果,比较耗费空间。
迭代的优缺点:迭代大部分时候需要人为的对问题进行剖析,将问题转变为一次次的迭代来逼近答案,一旦问题剖析完毕,就可以很容易的通过循环加以实现。
迭代的效率高,但却不太容易理解。