【算法】递归的简单应用

关于递归

简单来说,递归就是函数的重复调用。每一次函数调用都存储在栈中。当栈顶的函数执行完毕,才会执行栈中的下一个元素。
递归的几个注意点:

  1. 明白递归的函数正在进行什么操作,它做了什么事情?
  2. 在递归中必须要设置结束条件、明确结束条件,并且逐步靠近结束条件。不然会形成无限的递归。
  3. 递归就是有去(递去)有回(归来)。
  4. 相同重复逻辑,缩小问题的规模。
    参考文章

递归入门

阶乘

public static long f(int n){
        if(n == 1)   // 递归终止条件 
            return 1;    

        return n*f(n-1); 
    }

打印1~n

	public static void test(int n) {
		if (n > 1) {
			test(n - 1);
		} 
		//当打印出这句话时,一个test函数就运行完毕了。
			System.out.println("n=" + n);
	}

斐波那契数列

/**
     *斐波那契数列如下:
     * 每一项都是前两项之和。
     *  1,1,2,3,5,8,13,21,34,...
**/
	public static int fibonacci(int n) {
		if (n == 1 ||n==2) {     // 递归终止条件
			return 1;      
		}
		return fibonacci(n - 1) + fibonacci(n - 2); // 寻找逻辑关系
	}

递归进阶

迷宫问题

/**
 * @Author 不知名网友鑫
 * @Date 2022/3/12
 **/
public class MiGong {
    public static void main(String[] args) {
        //用一个二维数组来表示地图。
        int [][]map=new int[10][10];
        //四周打印墙壁(1)。
        for(int i=0;i<10;i++){
            map[0][i]=1;
            map[9][i]=1;
            map[i][0]=1;
            map[i][9]=1;
        }
        //从(1,1)开始走。
        setMap(map,1,1);
        for(int []row:map){
            for(int date:row){
                System.out.print(date);
            }
            System.out.println();
        }
    }
    public static boolean setMap(int [][]map,int i,int j){
        //当8,8表示找到出口。
        //设置迷宫策略。下右上左。
        if(map[8][8]==2) {
            //递归结束条件之一,找到出口及结束。
            return true;
        }else {
            //确认方向是否正确。!!!是不是为0.
            if(map[i][j]==0){
                map[i][j]=2;
                if(setMap(map, i+1, j)){
                    return true;
                }else if(setMap(map, i, j+1)){
                    return true;
                }else if(setMap(map, i-1, j)){
                    return true;
                }else if(setMap(map, i, j-1)){
                    return true;
                }else {
                    //递归结束条件之二,上下左右都没有出口(非0),就标记为不能走(3)。
                    map[i][j]=3;
                    return false;
                }
            }else {
                //递归结束条件之三,要走的位置非零,返回。
                return false;
            }
        }
    }
}

八皇后问题

主要的解释都在注释里了,认真看就一定可以看懂!


/**
 *  max 定义一共有多少个皇后。
 *  array[] 存放皇后放置位置结果。
 *  count 表示有多少种解法。
 *  judgeCount 表示判断冲突的次数。
 */
//关于array:array[i]=val 数组下标i+1表示第几个皇后、也表示第i+1行。val+1表示第几列。
//比如:array[8]={1,3,2,4,5,6,7,0}
// a[0]=1 -> 第一个皇后放在第一行,第2列。
// a[1]=3 —> 第二个皇后放在第二行,第4列。
public class Queue8 {
    private  int max=8;
    private int []array = new int[max];
    private static int count = 0;
    private static int judgeCount = 0;

    public static void main(String[] args) {
    Queue8 queue8=new Queue8();
    queue8.check(0);
        System.out.printf("一共有%d解法",count);
        System.out.printf("判断了冲突%d次",judgeCount);
    }
    //表示放入第n个皇后
    public void check(int n){
        //如果n==max,则表示已经放完了8个皇后。
        // 打印之后进行回溯,会将调整之前放置皇后的位置,继续进行接下来的步骤。
        if(n==max){
            print();
            return ;
        }
        //表示将第一个皇后放在第一行、第二行、依次进行。
        for(int i=0;i<max;i++){
            //先将第n个皇后放在第i+1行
            array[n]=i;
            //判断冲突
            if(judge(n)){
                //如果不冲突,就继续放下一个皇后。
                check(n+1);
            }
            //如果冲突,就将当前皇后向后移一位。
            //如果从i到max行都不满足条件,就会进行回溯,调整上一个皇后的位置。
        }
    }

    /**
     *
     * @param n 表示第几个皇后
     * @return
     */
    public boolean judge(int n){
        judgeCount++;
        //每次从第一个皇后开始,判断与第n个皇后是否在同一列,同一斜线
        for(int i=0;i<n;i++){
            //array[i]==array[n] 表示在同一行。
            //Math.abs(n-1) == Math.abs(array[n]-array[i]) 判断是否在同一斜线。
            if(array[i]==array[n] ||Math.abs(n-i) == Math.abs(array[n] - array[i])){
                return false;
            }
        }
        return true;
    }
    //打印array[],表示一种解法。
    public void print(){
        count++;
        for(int i=0;i<array.length;i++){
            System.out.print(array[i] + " ");
        }
        System.out.println();
    }
}

最后,如果这篇文章对你有帮助的话,不妨点个收藏再走哦!
⭐码字不易,求个关注⭐
⭐点个收藏不迷路哦~⭐

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sivan_Xin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值