线性数据结构之递归

本文通过两个经典示例——迷宫求解和八皇后问题,详细介绍了递归算法的工作原理及其在解决复杂问题时的优势。在迷宫问题中,采用递归回溯的方法寻找路径;而在八皇后问题中,利用递归实现皇后排列的回溯搜索,展示了递归在解决约束冲突问题上的实用性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

递归场景
在这里插入图片描述
在这里插入图片描述

实例


/**
 * 迷宫
 *
 * @author qb
 * @version 1.0
 * @since 2022/2/22 15:50
 */
public class MiGong {

    public static void main(String[] args) {
        //先创建一个二维数组 模拟迷宫
        //地图
        int[][] map = new int[8][7];
        //使用1表示墙,先把上下全部设置为1
        for (int i=0;i<7;i++){
            map[0][i] = 1;
            map[7][i] = 1;
        }
        //左右全部设置为1
        for (int i = 0; i < 8; i++) {
            map[i][0] = 1;
            map[i][6] = 1;
        }
        //设置挡板  用1表示
        map[3][1] = 1;
        map[3][2] = 1;
        //输出地图
        for (int i = 0; i < 8; i++) {

            for (int j = 0; j < 7; j++) {
                System.out.print(map[i][j] + " ");
            }
            System.out.println();
        }

        //使用递归回溯找路
        setWay(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();
        }

    }

    /**
     * 使用递归回溯给小球找路
     * 如果小球走到了map[6][5]则是找到了出路
     * 约定:当map[i][j] 为0表示该点没有走过,为1表示墙,2表示该路可以走,3表示该路走过,但是不通
     * 策略: 下->右->上->左,走不通回溯
     * @param map 地图
     * @param i 哪儿一行
     * @param j 那儿一列
     * @return 找到出路返回true ,否则反之
     */
    public static boolean setWay(int[][] map,int i,int j){

        if(map[6][5] == 2){
            return true;
        }
        else{
            if(map[i][j] == 0){
                //如果当前点没走过
                map[i][j] = 2;
                if(setWay(map,i+1,j)){
                    //向下
                    return true;
                }
                else if(setWay(map,i,j+1)){
                    //向右
                    return true;
                }
                else if(setWay(map,i-1,j)){
                    //向上
                    return true;
                }
                else if (setWay(map,i,j-1)){
                    //向左
                    return true;
                }else {
                    //说明该点是走不通的,死路
                    map[i][j] = 3;
                    return false;
                }
            }
            return false;
        }
    }

}

八皇后问题

在8x8格的棋盘上任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法

递归实现(性能比算法差) 会回溯15720次

package com.example.dataalgorithm.recursion;

/**
 * 8皇后问题  回溯实现
 * @author qb
 * @version 1.0
 * @since 2022/2/23 9:23
 */
public class Queue8 {

    /**
     * 1.定义一个max标识共有多少个皇后
     */
    int max = 8;

    /**
     * 定义数组,保存皇后放置位置的结果,比如arr = {0,4,7,5,2,6,1,3};
     */
    int[] array = new int[max];

    static int count = 0;

    static int num = 0;

    public static void main(String[] args) {
        //测试 8皇后是否正确
        Queue8 queue8 = new Queue8();
        queue8.check(0);
        System.out.println("一共有"+count+"种解法");
        System.out.println("一共判断冲突的次数:"+num+"次");
    }

    /**
     * 放置第n个皇后
     * @param n 第n个皇后
     */
    private void check(int n){
        //n=8时,8个皇后就已放好了
        if(n == max){
            print();
            return;
        }
        //依次放入皇后,并判断是否冲突
        for (int i = 0; i < max; i++) {
            //先把当前皇后(n),放到该行的第一列
            array[n] = i;
            //当放置第n个皇后到i列时,是否冲突
            if (judge(n)){
                //不冲突,接着放n+1个皇后,--递归
                check(n+1);
            }
            //如果冲突了,array[i] 便会向后放,因为i是循环递增的
        }
    }


    /**
     * 查看当我们放置第n个皇后,就去检测该皇后是否和前面已经摆放的皇后冲突
     * @param n 第n个皇后
     * @return 是否冲突
     */
    private boolean judge(int n){
        num++;
        for (int i = 0; i < n; i++) {
            //1.array[i] == array[n] 判断n是否和之前的皇后再同一列
            //2.Math.abs(n-i) == Math.abs(array[n] - array[i])  判断第n个皇后是否和第i个皇后再同一斜线
            if(array[i] == array[n] || Math.abs(n-i) == Math.abs(array[n] - array[i])){
                return false;
            }
        }
        return true;
    }


    /**
     * 将皇后摆放的位置输出
     */
    private void print(){
        count ++;
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i]+" ");
        }
        System.out.println();

    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值