• Java 之 递归&递归操作文件


    一、概述

      递归:指在当前方法内调用自己的现象。

      递归的分类

      •  递归分为两种,直接递归间接递归
      •    直接递归称为方法自身调用自己
      •    间接递归可以 A 方法调用 B 方法,B 方法调用 C 方法,C 方法调用 A 方法。

      注意

      •  递归一定要有条件限制,保证递归能够停止下来,否则会发生栈内存溢出。
      •     在递归中虽然有限定条件,但是递归次数不能太多,苟泽也会发生栈内容溢出。
      •     构造方法,进制递归。

      递归导致栈内存溢出的原理:

      

    二、案例

      1、递归累加求和

        计算 1~ n 的和,n 的累加 = n + (n+1) 的累和,可以把累和的操作定义成一个方法,递归调用。

        实现:

     1 public class Demo {
     2     public static void main(String[] args) {
     3         //计算1~num的和,使用递归完成
     4         int num = 5;
     5         // 调用求和的方法
     6         int sum = getSum(num);
     7         // 输出结果
     8         System.out.println(sum);
     9     } 
    10     /*
    11         通过递归算法实现.
    12         参数列表:int
    13         返回值类型: int
    14     */
    15     public static int getSum(int num) {
    16         /*
    17         num为1时,方法返回1,
    18         相当于是方法的出口,num总有是1的情况
    19         */
    20         if(num == 1){
    21             return 1;
    22         }
    23         /*
    24         num不为1时,方法返回 num +(num‐1)的累和
    25         递归调用getSum方法
    26         */
    27         return num + getSum(num‐1);
    28     }
    29 }

      代码执行图解

        注意递归一定要有条件限定,保证递归能够停止下来,次数不要太多,否则会发生栈内存溢出。

      2、递归求阶乘

        阶乘:所有小于及等于该数的正整数的积。

        分析:n! = n * (n-1);

        实现:

     1 public class DiGuiDemo {
     2     //计算n的阶乘,使用递归完成
     3     public static void main(String[] args) {
     4         int n = 3;
     5         // 调用求阶乘的方法
     6         int value = getValue(n);
     7         // 输出结果
     8         System.out.println("阶乘为:"+ value);
     9       }
    10  /* 
    11     通过递归算法实现.
    12     参数列表:int
    13     返回值类型: int
    14     */
    15     public static int getValue(int n) {
    16         // 1的阶乘为1
    17         if (n == 1) {
    18             return 1;
    19         } 
    20         /*
    21         n不为1时,方法返回 n! = n*(n‐1)!
    22        递归调用getValue方法
    23         */
    24         return n * getValue(n ‐ 1);
    25     }
    26 }

      3、递归求年龄

        问题:第一个人10,第2个比第1个人大2岁,以此类推,请用递归方式计算出第8个人多大?

        实现:

     1   public int getAge(int n){
     2         /*
     3          * 第一个人10,n=1, 结果10       
     4          * 第二个人12,n=2, 结果10 + 2       getAge(1) + 2
     5          * 第三个人14,n=3, 结果10 + 2 + 2   getAge(2) + 2
     6          * 
     7          * 第n个人?,n=?, 结果10 + 2 + 2 ...+ ?  getAge(n-1) + 2
     8          */
     9         if(n==1){
    10             return 10;
    11         }else{
    12             return getAge(n-1) + 2;
    13         }
    14     }

      4、递归—爬台阶问题

        问题:有n步台阶,一次只能上1步或2步,共有多少种走法?

        实现:

     1   public long sum(int n){
     2         /*
     3          * n==1  1
     4          * n==2  2  
     5          * n==3  最后一步  要么从第1级跨2步,要么从第2级跨1步        把走到第1级的走法 + 走到第2级的走法  sum(1) + sum(2)
     6          * n==4 最后一步  要么从第2级跨2步,要么从第3级跨1步        把走到第2级的走法 + 走到第3级的走法  sum(2) + sum(3)
     7          * n==5 最后一步  要么从第3级跨2步,要么从第4级跨1步        把走到第3级的走法 + 走到第4级的走法  sum(3) + sum(4)
     8          * 
     9          * n=? 最后一步  要么从第n-2级跨2步,要么从第n-1级跨1步        把走到第n-2级的走法 + 走到第n-1级的走法  sum(n-2) + sum(n-1)
    10          */
    11         if(n==1 || n==2){
    12             return n;
    13         }else{
    14             return sum(n-1) + sum(n-2);
    15         }
    16     }

    三、递归与文件操作

      1、递归打印多级目录

        分析:多级目录的打印,就是当目录的嵌套。遍历之前,无从知道到底有多少级目录,所以我们还是要使用递归实现。

        实现1:

     1 public class DiGuiDemo {
     2     public static void main(String[] args) {
     3         // 创建File对象
     4         File dir = new File("D:\aaa");
     5         // 调用打印目录方法
     6         printDir(dir);
     7     } 
     8     public static void printDir(File dir) {
     9         // 获取子文件和目录
    10         File[] files = dir.listFiles();
    11         // 循环打印
    12         /*
    13         判断:
    14         当是文件时,打印绝对路径.
    15         当是目录时,继续调用打印目录的方法,形成递归调用.
    16         */
    17         for (File file : files) {
    18             // 判断
    19             if (file.isFile()) {
    20                 // 是文件,输出文件绝对路径
    21                 System.out.println("文件名:"+ file.getAbsolutePath());
    22             } else {
    23                 // 是目录,输出目录绝对路径
    24                 System.out.println("目录:"+file.getAbsolutePath());
    25                 // 继续遍历,调用printDir,形成递归
    26                  printDir(file);
    27             }
    28         }
    29   }
    30 }

         实现2:

     1    //listAllSub()方法的功能是列出一个文件或一个目录及它的下一级
     2     public void listAllSub(File dir){
     3         if(dir.isDirectory()){
     4             File[] listFiles = dir.listFiles();
     5             for (File sub : listFiles) {//sub可能是一个文件,也可能是一个文件夹
     6                 listAllSub(sub);//递归:自己调用自己
     7             }
     8         }
     9         System.out.println(dir);
    10     }

      2、递归求文件或目录大小

        实现:

     1   public long getLength(File dir){
     2         if (dir != null && dir.isDirectory()) {
     3             File[] listFiles = dir.listFiles();
     4             if(listFiles!=null){
     5                 long sum = 0;
     6                 for (File sub : listFiles) {
     7                     sum += getLength(sub);
     8                 }
     9                 return sum;
    10             }
    11         }else if(dir != null && dir.isFile()){
    12             return dir.length();
    13         }
    14         return 0;
    15     }

      3、递归删除文件 

       实现:

     1   public void deleteDir(File file){
     2         //如果是文件夹,先把它的下一级删除
     3         if(file.isDirectory()){
     4             File[] listFiles = file.listFiles();
     5             //经过这个foreach循环,可以把file的所有的下一级删除
     6             for (File sub : listFiles) {
     7                 deleteDir(sub);
     8             }
     9         }
    10         
    11         //文件夹就变成了空文件夹,就可以直接删
    12         //如果是文件也可以直接删除
    13         file.delete();
    14     }

     

  • 相关阅读:
    01Python基础_02变量
    01Python基础_04输入输出方式
    01Python基础_03运算符
    Spring Cloud 入门教程 搭建配置中心服务
    Spring Cloud入门教程Hystrix断路器实现容错和降级
    Spring Boot 2.0.1 入门教程
    Spring Cloud入门教程Ribbon实现客户端负载均衡
    Spring Cloud 入门教程 Eureka服务注册与发现
    代理模式
    最短路径算法——Dijkstra and Floyd算法
  • 原文地址:https://www.cnblogs.com/niujifei/p/11482041.html
Copyright © 2020-2023  润新知