Java数据结构实现之递归和相关递归题目

导读:本篇文章讲解 Java数据结构实现之递归和相关递归题目,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

目录

一.递归的概念

二.递归的调用机制

三.使用递归需要注意的问题

四.递归相关问题之迷宫问题

1.迷宫模型

2.问题分析

3.代码实现

4.问题的拓展

五.递归相关问题之八皇后问题

1.八皇后问题介绍

2.八皇后问题算法思路分析

3.代码的实现

4.问题的分析


一.递归的概念

简单的说:递归就是方法自己调用自己,每次调用时传入不同的变量.递归有助于编程者解决复杂的问题,同时可以让代码变得简洁。

二.递归的调用机制

1)打印问题

public class testRecursion {
    public static void main(String[] args) {
        print(5);

    }

    public static void print(int n) {
        if (n > 2)
            print(n - 1);

        System.out.println(n);
    }
}

输出结果:

2

3

4

5

2)阶乘问题

public class testRecursion {
    public static void main(String[] args) {
        int factorial = factorial(5);
        System.out.println(factorial);

    }

 public static int factorial(int n) {
        if (n > 1)
            return n * factorial(n - 1);
        else
            return 1;
    }
}

输出结果:

120

递归调用规则:
1.当程序执行到一个方法时,就会开辟一个独立的空间(栈)

2.每个空间的数据(局部变量),是独立的.

Java数据结构实现之递归和相关递归题目

三.使用递归需要注意的问题

1)执行一个方法时,就创建一个新的受保护的独立空间(栈空间).

2)方法的局部变量是独立的,不会相互影响,比如n变量.

3)如果方法中使用的是引用类型变量(比如数组),就会共享该引用类型的数据.

4)递归必须向退出递归的条件逼近,否则就是无限递归,出现StackOverflowError,死归了:)

5)当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕。

四.递归相关问题之迷宫问题

1.迷宫模型

对如图所示的迷宫,需要找到箭头所对的出路,该如何设计

Java数据结构实现之递归和相关递归题目

2.问题分析

对于迷宫问题,我们应该使用递归来解决,先做如下规定:

当map,0表示该点没有走过,1表示墙;2表示经走过,3表示走过但是走不通

在走迷宫时,需要确定一个策略(方法) 下->右->上->左,如果走不通,回溯

我们要用二维数组来模拟迷宫的模型,如图所示为设置的一个迷宫

Java数据结构实现之递归和相关递归题目

其中1为墙,为不能走的部分.当我们的出发(1,1)位置的时候,根据我们设定的策略,我们首先是朝下面行进的,到达(2,1)位置,之后再向下面行进,发现此路不通,此时应该返回(2,1)位置,之后根据策略朝右走,到达(2,2),以此类推,…….之后到达了(4,3)的位置,发现下,左,右都不可走,而且上面的路已经走过,说明此时路为死路,置此位置为3,之后返回(3,3)位置,同样为死路,以此类推,最后可以到达最终位置(6,5)的位置,返回true,可以找到出路.

3.代码实现

public class maze {
    public static void main(String[] args) {
        //创建一个二维数组模拟迷宫
        int[][] map = new int[8][7];
        //使用不同项目表示墙
        for (int i = 0; i < 7; i++) {
            map[0][i] = 1;
            map[7][i] = 1;
        }
        for (int i = 0; i < 8; i++) {
            map[i][0] = 1;
            map[i][6] = 1;
        }
        map[3][1] = 1;
        map[3][2] = 1;
        map[4][2] = 1;
        map[5][3] = 1;
        map[4][4] = 1;
        map[3][4] = 1;
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 7; j++) {
                System.out.print(map[i][j] + "  ");
            }
            System.out.println();
        }
        //使用递归回溯给小人找路
        findRoad(map, 1, 1);
        System.out.println("----------------------------");
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 7; j++) {
                System.out.print(map[i][j] + "  ");
            }
            System.out.println();
        }


    }
    //使用递归给小球找路

    /**
     * @param map 地图
     * @param i   开始的行
     * @param j   开始的列
     *            (i,j)表示开始的位置
     *            如果小球能到(6,5)的位置,返回true,否则返回false
     *            约定:当map,0表示该点没有走过,1表示墙;2表示经走过,3表示走过但是走不通
     *            在走迷宫时,需要确定一个策略(方法)  下->右->上->左,如果走不通,回溯
     * @return
     */
    public static boolean findRoad(int[][] map, int i, int j) {
        if (map[6][5] == 2)  //表示通路已经走过
            return true;
        else {
            if (map[i][j] == 0) {
                map[i][j] = 2;
                if (findRoad(map, i + 1, j)) {//向下走
                    return true;
                } else if (findRoad(map, i, j + 1)) {//向右走
                    return true;
                } else if (findRoad(map, i - 1, j)) {//向上走
                    return true;
                } else if (findRoad(map, i, j - 1)) {//向左走
                    return true;
                } else {
                    //说明此路走不通,是死路
                    map[i][j] = 3;
                    return false;
                }
            } else
                return false;

        }


    }

}

结果

Java数据结构实现之递归和相关递归题目

 2即为使用此策略走出来的路径

4.问题的拓展

已知迷宫,求最短路径.

我们可以知道,迷宫路径的长短只和我们设定的策略有关,只需要对比每一种策略的路径长度,选出最短的那一种即可.总共有24种策略,需要统计出24种,然后进行比较.代码省略

五.递归相关问题之八皇后问题

1.八皇后问题介绍

八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,

即:任意两个皇后都不能外干同一行、同一列或同一斜线上,问有多少神摆法。

Java数据结构实现之递归和相关递归题目

2.八皇后问题算法思路分析

1)第一个皇后先放第一行第一列
2)第二个皇后放在第二行第一列、然后判断是否OK,如果不OK,继续放在第二列、第三列、依次把所有列都放完,找到一个合适
3)继续第三个皇后,还是第一列、第二列…..直到第8个皇后也能放在一个不冲突的位置,算是找到了一个正确解
4)当得到一个正确解时,在栈回退到上一个栈时,就会开始回溯,即将第一个皇后,放到第一列的所有正确解,全部得到.
5)然后回头继续第一个皇后放第二列,后面继续循环执行1,2,3,4的步骤【示意图】

说明:理论上应该创建一个二维数组来表示棋盘,但是实际上可以通过算法,
用一个一维数组即可解决问题. arr[8] = {0 ,4,7,5,2,6,1,3}//对应arr下标表示第几行,即第几个皇后,arr[i]= val , val表示第i+1个皇后放在第i+1行的第val+1列

3.代码的实现

public class Queue {
    //定义一个max表示有多少个皇后
    int max = 8;
    //定义一个数组array,保存皇后放置位置的结果
    int[] arr = new int[max];
    static int count = 0;

    public static void main(String[] args) {
        Queue queue = new Queue();
        queue.check(0);
        System.out.println("总共有" + count + "种解法");

    }

    //编写一个方法,放置第n个皇后
    //每一次check方法里面,都有依次for循环,因此会有回溯
    public void check(int n) {

        if (n == max) {  //n==8,其实
            print();
            return;
        }
        //依次放入皇后,并判断是否冲突
        for (int i = 0; i < max; i++) {
            //先把当前这个皇后n,放在第i列
            arr[n] = i;
            //判断放置当前皇后n到第i行时,是否冲突
            if (judge(n)) {  //不冲突
                check(n + 1);
            }
            //如果冲突,就继续执行arr[n]=i,将此皇后放置在第i+1个位置


        }


    }

    //查看当我们放置第n个皇后,就去检测该皇后是否与前n-1个冲突
    public boolean judge(int n) {
        for (int i = 0; i < n; i++) {
            //在同一列,或者在同一条斜线,则不满足条件返回false
            if (arr[i] == arr[n] || Math.abs(n - i) == Math.abs(arr[n] - arr[i])) {
                return false;
            }

        }
        return true;

    }

    //写一个方法,可以将皇后摆放的位置输出
    public void print() {
        count++;
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "   ");
        }
        System.out.println();

    }
}

打印结果

Java数据结构实现之递归和相关递归题目

4.问题的分析

虽然递归解决八皇后问题代码简单,但是运算的量很大,需要上千次判断

Java数据结构实现之递归和相关递归题目

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/101081.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!