什么是递归

我先看下百度百科的解释:

一种计算过程,如果其中每一步都要用到前一步或前几步的结果,称为递归的。用递归过程定义的函数,称为递归函数,例如连加、连乘及阶乘等。凡是递归的函数,都是可计算的,即能行的 。

古典递归函数,是一种定义在自然数集合上的函数,它的未知值往往要通过有限次运算回归到已知值来求出,故称为“递归”。它是古典递归函数论的研究对象 。

简单的说,递归一定要有递归体头和递归体。

递归头:什么时候不调用自己方法,即递归的结束条件

递归体:什么时候需要调用自己方法,即自己调用自己

如果一个方法没有递归头jvm在运行方法时,就会不断开辟栈幁(Stack Frame) 造成栈溢出,抛出 java.lang.StackOverflowError 异常。

我们看下面代码:

package com.xzlf.recursion;

public class Test {
public static void main(String[] args) {
a();
} public static void a() {
System.out.println("Test.a()");
a();
} }

显然在a() 方法中没有终止调用a() 方法的条件,那么就会一直调用下去,直到吧栈内存用完。所以以上代码运行时,会一种执行打印语句,然后在栈溢出是抛出异常。

下面是代码运行结果:



如果我们加上一个终止条件就不会有无限调用情况了:

package com.xzlf.recursion;

public class Test {
public static int num = 10;
public static void main(String[] args) {
a();
} public static void a() {
num--;
System.out.println("Test.a() " + num);
if(num > 0) {
a();
}
} }

修改后程序运行结果:



好了程序在不满足条件时,终止调用,我们的递归完成了。

递归应用

求阶乘

其实阶乘我们用普通for循环后while循环也能实现

/**
* 普通while循环球阶乘
* @param n
* @return
*/
public static long factorialForWhile(int n) {
long result = 1;
while(n > 1) {
result *= n ;
n --;
}
return result;
}

使用递归写法:

/**
* 递归算法球阶乘
* @param n
* @return
*/ public static long factorial(int n) {
// 递归头
if(n == 1) {
return 1;
}
// 递归体
return n * factorial(n-1);// n! = n * (n - 1)
}

测试以上代码:

public static void main(String[] args) {
int n = 10;
long r1 = factorial(n);
long r2 = factorialForWhile(n);
System.out.println("递归算法结果:" + r1);
System.out.println("while循环结果:" + r2);
}

以上运行结果为:



可以看到两种写法得到的结果一样。

打印文件信息

我们来打印tomcat/webapp下面一个mananger目录下文件信息,并使用 “-”来缩进表示层级:

/**
* 打印文件信息
* @param file 文件名称
* @param level 层次数(实际就是:第几次递归调用)
*/
public static void printFile(File file, int level) {
// 输出层次
for (int i = 0; i < level; i++) {
System.out.print("-");
}
// 输出文件名
System.out.println(file.getName()); //如果file是目录,则获取子文件列表,并对每个子文件进行相同的操作
if(file.isDirectory()) {
File[] listFiles = file.listFiles();
for (File f : listFiles) {
//递归调用该方法:每调用一次层次+1
printFile(f, level + 1);
}
}
}

求斐波那契数列

斐波那契数列,有些地方说从0开始,有些地方说从1开始???

看百度百科怎么说:

斐波那契数列指的是这样一个数列:



自然中的斐波那契数列 自然中的斐波那契数列 这个数列从第3项开始,每一项都等于前两项之和。

我们按百度百科的方法用java代码实现:

/**
* 计算斐波那契数列
* @param n
* @return
*/
public static long fibRec(int n) {
if(n == 1 || n == 2) {
return 1;
}
return fibRec(n - 1) + fibRec(n - 2);
}

打印文件和斐波那契数列完成代码及测试

package com.xzlf.recursion;

import java.io.File;

public class RecursionApp {

	public static void main(String[] args) {
File file = new File("D:/Tomcat/apache-tomcat-7.0.69/webapps/manager");
printFile(file, 0); // 使用递归打印文件信息
System.out.println("=====================");
long fibRec = fibRec(10); // 使用递归计算斐波那契数列
System.out.println(fibRec);
} /**
* 打印文件信息
* @param file 文件名称
* @param level 层次数(实际就是:第几次递归调用)
*/
public static void printFile(File file, int level) {
// 输出层次
for (int i = 0; i < level; i++) {
System.out.print("-");
}
// 输出文件名
System.out.println(file.getName()); //如果file是目录,则获取子文件列表,并对每个子文件进行相同的操作
if(file.isDirectory()) {
File[] listFiles = file.listFiles();
for (File f : listFiles) {
//递归调用该方法:每调用一次层次+1
printFile(f, level + 1);
}
}
} /**
* 计算斐波那契数列
* @param n
* @return
*/
public static long fibRec(int n) {
if(n == 1 || n == 2) {
return 1;
}
return fibRec(n - 1) + fibRec(n - 2);
}
}

代码运行结果:

java 递归及其经典应用--求阶乘、打印文件信息、计算斐波那契数列的更多相关文章

  1. Java经典案例之-判断兔子的数量(斐波那契数列)

    /** * 描述:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子, * 假如兔子都不死,问每个兔子总数为多少? * 分析:根据题目条件可以推断 * 兔子的规律 ...

  2. C#递归、动态规划计算斐波那契数列

    //递归         public static long recurFib(int num)         {             if (num < 2)              ...

  3. 算法 递归 迭代 动态规划 斐波那契数列 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  4. 【递归】斐波那契数列第n个数

    递归.递推计算斐波那契数列第n项的值: #include <stdio.h> long long fact(int n); //[递推]计算波那契数列第n个数 long long fact ...

  5. Java算法求最大最小值,冒泡排序,斐波纳契数列一些经典算法<不断更新中>

    清明在家,无聊,把一些经典的算法总结了一下. 一.求最大,最小值 Scanner input=new Scanner(System.in); int[] a={21,31,4,2,766,345,2, ...

  6. Java算法求最大最小值,倒序,冒泡排序,斐波纳契数列,日历一些经典算法

    一,求最大,最小值 int[] a={21,31,4,2,766,345,2,34}; //这里防止数组中有负数,所以初始化的时候给的数组中的第一个数. int max=a[0]; int min=a ...

  7. 【Java】斐波那契数列(Fibonacci Sequence、兔子数列)的3种计算方法(递归实现、递归值缓存实现、循环实现、尾递归实现)

    斐波那契数列:0.1.1.2.3.5.8.13………… 他的规律是,第一项是0,第二项是1,第三项开始(含第三项)等于前两项之和. > 递归实现 看到这个规则,第一个想起当然是递归算法去实现了, ...

  8. 斐波那契数列(递归)&求100以内的素数

    Java 5 添加了 java.util.Scanner 类,这是一个用于扫描输入文本的新的实用程序.它是以 前的 StringTokenizer 和 Matcher 类之间的某种结合.由于任何数据都 ...

  9. Python3基础 函数 递归 阶乘与斐波那契数列

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

随机推荐

  1. 模块 face_recognition 人脸识别

    face_recognition 人脸识别 api 说明 1 load_image_file 将img文件加载到numpy 数组中 2 face_locations 查找图像中所有面部和所有面部特征的 ...

  2. Markdown语法快速学习

    Markdown 简洁语法说明 0.前言 一直以来都是以word文档做笔记,存在很多问题,比如代码格式.高亮等.这次公司要求使用markdown,感觉眼前一亮,以前word的问题都得到了解决,而且可以 ...

  3. 1044 Shopping in Mars (25分)(二分查找)

    Shopping in Mars is quite a different experience. The Mars people pay by chained diamonds. Each diam ...

  4. 1035 Password (20分)(水)

    To prepare for PAT, the judge sometimes has to generate random passwords for the users. The problem ...

  5. Kubernetes Pod钩子

    目录 1.Pod容器钩子最终目的 2.何为Pod容器钩子 3.基于PostStart演示 4.基于PreStop演示 5.优雅停止Java应用 1.Pod容器钩子最终目的 之前在生产环境中使用dubb ...

  6. 命令行工具nslookup查域名DNS服务器

    在使用的操作系统里进入终端, 1.输入 nslookup 回车 2.输入 set type=ns 回车 3.输入域名(不带WWW的),如:baidu.com 回车 操作过程如下, > set t ...

  7. springboot actuator 配置安全

    springboot actuator监控是什么?类似php的phpinfor()函数,不过actuator更强大,可以查看的数据.状态更多.Actuator是Spring Boot提供的对应用系统的 ...

  8. python 函数--内置函数

    一.内置函数 内置函数是python自带的一系列常用函数. 二.python3中内置函数     内置功能     abs() delattr() hash() memoryview() set() ...

  9. Linux基础篇,文本数据的比较与排序:sort、uniq、comm、diff

    一.sort sort命令用于将文本文件内容以行排序 sort [选项参数] [-o<输出文件>] [-t<分隔字符>] [+<起始栏位> -<结束栏位> ...

  10. Flask 入门(一)(Mac 系统)

    熟话说,万事开头难,为了运行这第一个程序,我可是碰了不少壁,接下来我将正确的方法交给大家. 1.首先得有python和虚拟环境 (1)python环境苹果系统自带 (2)虚拟环境: 安装virtual ...