Java 初识递归

Java 递归

digui

  • 什么是递归
    • 递归: 即在成员方法内调用自身
  • 递归的优点
    • 能用简洁的代码解决复杂的问题
  • 递归的缺点
    • 对内存的消耗大
  • 递归的应用场景
    • 当我们要获取一个结果,但是这个结果依赖与上一步一样操作所得到的结果,才能进行运算时,可以使用递归
    • 回溯:有多个选择,但不确定哪个是正确的可以使用递归的回溯现象进行逐一尝试

递归的使用

即在成员方法内调用自身方法

public class ...... {
    // 实例化对象
    Recursion func = new Recursion();
    // 调用 function 方法
    func.function(10);
}

class Recursion {
    public void function (int number) {
        if (number == 1) {
            return;
        }
        System.out.println(number);
    }
}

递归的注意事项

  1. 因为JVM会为每个调用的方法单独开辟一个临时栈,每调用一次开辟一个,只要方法不结束,这个栈就会一直存在,所以递归的层次不能太多次。
  2. 递归一定要有出口,即:退出条件
  3. 递归必须拥有最少一个形参

递归的经典应用

阶乘

public class ...... {
    // 实例化对象
    Recursion object = new Recursion();
    // 调用 阶层 方法
    object.factorial(10);
}

class Recursion {
    /**
     * @param number 阶乘层数
     * @return 阶层结果
    */
    public int factorial (int number) {
        if (number == 1) {
            // 当 number = 1 时退出递归
            return 1;
        }
        // 利用上一层的结果 来计算
        // factor...(number - 1) * 2
        // factor...(number - 1) * 3
        // factor...(number - 1) * 4......
        return factorial(number - 1) * number;
    }
}

递归的回溯现象

回溯也是递归的常用方法,如:

  • 当前有n个方案,方案1、方案2、方案3......,我们不确定哪个方案是能解决问题
  • 先尝试方案1 方案1能通过执行后续代码
  • 如不同通过尝试方案2以此类推

如寻路案例

public class ...... {
    public static void main (String[] args) {

        Map mapObject = new Map();
        int map[][] = mapObject.genMap(8, 7);
        System.out.println("寻路结果如下:\n" + mapObject.findWay(map, 1, 1));
        // 打印寻路结果
        new Arrayss().printArrays(map);

        
    }
}

class Map {
    // 用于记录出口位置
    int exportX;
    int exportY;
    /**
     * 生成地图
     * @param row 行
     * @param column 列
     * 0 表示可走 
     * 1 表示障碍物
    */
    public int[][] genMap (int row, int column) {
        int map[][] = new int[row][column];
        // 生成一个四边围的地图
        for (int rows = 0; rows < row; rows++) {
            for (int columns = 0; columns < column; columns++) {
                if (rows == 0 || rows == row - 1 || columns == 0 || columns == column - 1) {
                    map[rows][columns] = 1;
                }
            }
        }
        // 随机生成1~10个障碍物
        for (int randomCount = 1; randomCount <= (int)(Math.random() * 10) + 1; randomCount++) {
            // 随机指定可活动行
            int randomRow = (int)(Math.random() * (row - 2)) + 1;
            // 随机指定可活动列
            int randomColumn = (int)(Math.random() * (column - 2)) + 1;
            // 随机位置生成障碍物
            map[randomRow][randomColumn] = 1;
        }
        // 记录随机出口位置
        exportX = (int)(Math.random() * (column - 2)) + 1;
        exportY = (int)(Math.random() * (row - 2)) + 1;
        map[exportY][exportX] = 2;

        // 打印地图未寻路前
        new Arrayss().printArrays(map);
        map[exportY][exportX] = 0;
        return map;
    }
    
    /**
     * @param map 地图
     * @param x 当前位置x坐标
     * @param y 当前位置y坐标
     * @return boolean 此位置是否可通
    */
    public boolean findWay (int map[][], int x, int y) {
        switch (map[exportY][exportX]) {
        	// 如果 出口位置等于2
        	// 说明程序已经走到出口位置,返回true
            case 2:
                return true;
            // 处理当前位置不为出口位置的情况
            default:
                switch (map[y][x]) {
                    // 当前位置为 0 说明可进行尝试
                    case 0:
                        // 假定当前位置可从上下左右其中一个走同
                        map[y][x] = 2;
                        // 尝试向下寻路
                        if (findWay(map, x, y+1)) {
                            return true;
                        }
                        // 尝试向右寻路
                        else if (findWay(map, x+1, y)) {
                            return true;
                        }
                        // 尝试向左寻路
                        else if (findWay(map, x-1, y)) {
                            return true;
                        }
                        // 尝试向上寻路
                        else if (findWay(map, x, y-1)) {
                            return true;
                        }
                        // 如果四个方向都不通
                        else {
                            // 将当前位置记录为 3 并返回false
                            map[y][x] = 3;
                            return false;
                        }
                    default:
                        // 当前位置不为 0 说明是死路返回false并退出
                        return false;
                }
        }
    }
}

class Arrayss {
    public void printArrays (int array[][]) {
        for (int twoDimensional = 0; twoDimensional < array.length; twoDimensional++) {
            for (int index = 0; index < array[twoDimensional].length; index++) {
                System.out.print(array[twoDimensional][index] + " ");
            }
            System.out.println();
        }
    }
}
posted @   假文艺青年。  阅读(50)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
点击右上角即可分享
微信分享提示