递归 ———— java代码解读(1)

基本思想: 用一个方法通过调用自身来实现任务。

注: 为防止发生无穷递归,要设置“基础情形” 程序中通常用 if-else 来实现。
分类:直接递归与间接递归

实例: 走迷宫
思维: 解决迷宫问题要考虑大量的试验和错误,一条路走不通,要回溯,然后尝试另一条路。

思考:如何使用基础情形来结束递归?

目标:创造一个迷宫。 用二维数组来表示。 初始: 1表示通路,0表示不通。目标:从左上角进,从右下角出。

//maze.java
public class maze{
    private final int TRIED = 3; // final 关键字定义的变量不可被更改(用大写)
    private final int PATH = 7; // 这里我们用 3 表示尝试过的路径,用7表示可以走通的路径
    private int[][] grid = {{1,1,1,0,1,1,0,0,0,1,1,1,1},
                            {1,0,1,1,1,0,1,1,1,1,0,0,1},
                            {0,0,0,0,1,0,1,0,1,0,1,0,0},
                            {1,1,1,0,1,1,1,0,1,0,1,1,1},
                            {1,0,1,0,0,0,0,1,1,1,0,0,1},
                            {1,0,1,1,1,1,1,1,0,1,1,1,1},
                            {1,0,0,0,0,0,0,0,0,0,0,0,0},
                            {1,1,1,1,1,1,1,1,1,1,1,1,1}
                            };   //创建二维数组 作为迷宫
    public boolean traverse(int row, int column){
    //主函数 只能“上下左右”四个方向走
        boolean done = false; //done 表示一条路是否可以走通。 用布尔类型
        if (valid(row,column)){ // 调用检测边界函数 (为true还在迷宫内部)
            grid[row][column]=TRIED; //该cell被尝试过了
            if (row == grid.length-1 && column == grid[0].length-1)
            //这是递归的基础情形, 如果达到位置(7,12)说明走出迷宫 
            //(注 迷宫共8行13列, 而数组是从0开始的)
                done = true; // 走出迷宫
            else{
                done = traverse(row+1,column); //递归调用 往下走
                if (!done) //donefalsedone = traverse(row,column+1);//right
                if(!done)
                    done = traverse(row-1,column);//up
                if(!done)
                    done = traverse(row,column-1);//left
            }
            if (done)
                grid[row][colum]=PATH;
        }
        return done;
    } 

    public boolean valid(int row, int column){
    // 判断是否到达迷宫边界
        boolean result = false;
        if (row>=0 && row<grid.length && column>=0 && column<grid[0].length) //判断cell是否还在迷宫内部
            // 二维数组:array.length   第一维的长度
            // array[0].length  第二维的长度
                ifgrid[row][column] == 1){
                    //检测该cell没有被尝试过或者走过
                    result = true;
                }
        return result;
    }
    public String toString(){
    //重写String 以便以要求的格式输出
    String redult = "\n";
    for (int row=0;row<grid.length;row++){
        for(int column=0;row<grid[row].length;column++)
            result += grid[row][column]+" "
        result += "\n"
    }
    return result;
    }
}



//Mazemain.java
public class Mazemain{
    public static void main(String args[]){
        maze laby = new maze();
        System.out.println(laby);
        if (laby.traverse(0,0))
            System.out.println("the maze was successfully traversed");
        else
            System.out.println("no way");
        System.out.println(laby)
    }
}

实际情况中,用来结束递归的基础情形可能有三种:
1 因为越出边界,导致一个不可行的移动
2 曾经尝试过而导致一个不可行的移动
3 到达最终位置

如果当前位置不是右下角,再从每个基本方向中寻找可行路径。先向下,调用traverse()将新位置作为参数。我们可以认为,每次递归调用,就是开始走一个新的简单一些的迷宫。
下-右-上-左 按照这四个方向 逐步尝试。先尝试从当前位置向下走,如果找不到通路,向右走,如果还是失败,向上走,最后尝试向左走。
如果在当前位置找到通路,则网格中值改为7.
经过不断的递归调用,第一个7写入右下角,下一个7写入能达到右下角的位置,继续该过程,知道最后一个7写入左上角。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值