您的位置:首页 > 编程语言 > Java开发

JavaSE第八十八讲:递归详解以及递归在阶乘与斐波那契数列的使用

2013-01-19 22:52 399 查看
1. 递归(Recursion)

所谓递归(Recursion),就是方法调用自身。对于递归来说,一定有一个出口,让递归结束,只有这样才能保证不出现死循环。

对于递归来说,调试起来也是比较麻烦的,因为递归是自己在调用自己。每一次调用都要再自己的方法里面找出它们的规律

2. 递归在阶乘中的运用

package com.ahuier.io;

public class Test1 {

//循环方式计算机阶乘,又叫做迭代的方式
public int compute(int number){
int result = 1;
for(int i = number; i > 0; i--){
result = result * i;
}
return result;
}

//使用递归方式计算机阶乘
public int compute2(int number){

//递归出口,当number等于1时
if(1 == number){
return 1;
}
else{
return number * compute2(number - 1);
}
}

public static void main(String[] args){
Test1 test = new Test1();
System.out.println(test.compute(5));
System.out.println(test.compute2(5));
}
}
编译执行结果:
120

120

【程序说明】:

阶乘:n! = n * (n - 1) * (n - 2) * ... * 2 * 1

等价:n! = n * (n - 1)!    
-------------->(1式计算n!必须知道(n-1)!)

同理:(n - 1)! = (n - 1) * (n - 2)! ------>(计算(n-1)!必须知道(n-2)!)

...

所以如此重复相同算法,计算的过程是一样的,一直到计算1的继承为止。

上式1也可以写成函数形式:f(x) = n * f(x - 1)

【调用】上述程序中整个递归的调用过程如下:

5 * compute2(4)

4 * compute2(3)

3 * compute2(2)

2 * compute2(1)

【返回】此时number为1程序返回1后程序返回的过程如下:

2 * 1

3 * 2 * 1

4 * 3 * 2 * 1

5 *4
* 3 * 2 * 1

所以输出结果为120

3. 递归在斐波那契数列中的运用

斐波纳契数列,又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、21、……



在数学上,斐波纳契数列以如下被以递归的方法定义:F0 = 0,F1 = 1,Fn
= F(n - 1) + F(n - 2)(n>=2,n∈N*)


上面的数列中,要求出一个值必然是要知道前面一个和前面第二个的值。当推到第一个或者第二个数字是1的时候,则为递归出口。

程序如下:

package com.ahuier.io;

/*
* 递归解斐波那契数列:1、1、2、3、5、8、13、21......
*/
public class Fab {

//n 表示数列中第几个数字
public int compute(int n){

//递归出口
if(n == 1 || n == 2){
return 1;
}
else{
//对于斐波那契数列中的第三个或者第三个以上的任意数字的值等于前两个值的和
return compute(n - 1) + compute(n - 2);
}
}
public static void main(String[] args) {
Fab fab = new Fab();
System.out.println(fab.compute(9));
}

}

编译执行结果:
34

【说明】:递归的难主要是难在他的思想上。

3. 递归在File类中的使用

在上一讲中,我们知道了File类的基本使用方法,其中有一个是delete()删除一个目录或者文件的方法,这边要注意的是delete()方法删除目录的时候,如果目录里面包含了目录或者文件,则这个目录是删不掉的。

查看JDK Doc文档中的File类delete()使用方法。

对于一个有包含目录和文件的目录来说,要想删除这个目录,则首先要检查这个目录里面是否有文件,如果有文件,则将所有的文件删掉,然后再把自身删除,如果这个目录里面除了包含文件外还有其他的目录,同样也是先把这些目录底下的文件全部删除,再删除自身,然后退到上一级再进行同样的删除操作。这其实是一个递归的过程。

写一个程序,删除一个目录下的所有目录和文件。

package com.ahuier.io;

import java.io.File;

/*
* 删除指定目录下的所有子目录或者文件
* 注意这个程序的实现只有通过递归才能实现的,其他的方法是实现不了的。
*/
public class FileTest9 {

public static void deleteAll(File file){
/*
* 递归的出口点:
* 第一个返回点是:如果待删除的目标file是一个真正的文件,直接删掉
* 第二个返回点是:如果目标是一个目录,这个目录是空的,直接删掉
*/
if(file.isFile() || file.list().length == 0){
file.delete();
}
else{
File[] files = file.listFiles(); //要删除这个目录,必须先删除目录底下的内容,所以先获得了待删除的目录内容
//遍历这个目录
for(File f : files){
deleteAll(f); //如果这个目录里面还有目录,则同样执行这个方法,表示删除这个目录,先删除该目录底下的内容
f.delete(); //然后再删除自己
}
}
}
public static void main(String[] args) {
deleteAll(new File("C:/abc"));

}
}
编译执行后删除目录"C:/abc"下的所有内容。

4. 递归作业:给定任意一个目录,以树形方式展现出该目录中的所有子目录和文件。另外,在展现的时候将目录排在上面,文件排在下面。每一层要加上缩进。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: