递归

递归就是方法不断的调用方法本身,每次调用时,传入不同的变量

递归每调用一次方法本身,就将方法压入栈中,执行完栈顶的方法后,将结果返回,方法依次出栈,最后全部出栈.递归调用完毕

样列一
阶乘的运算
问题描述:

大于等于0

0的阶乘: 0!=1;

1的阶乘: 1!=1;

任何大于等于1 的自然数n 阶乘表示方法:

n!=1 x 2 x 3 x … x(n-1) x n ;

/**
 * 阶乘运算
 */
public class FactorialOperator {


    /**
     * 阶乘与运算
     *
     * @param input
     * @return
     */
    public int calculate(int input) {
        if (input < 0) {
            throw new RuntimeException("输入数不能小于零");
        }

        return factorial(input);
    }


    /**
     * 0!=1
     * 1!=1
     * 阶乘运算
     *
     * @param n
     * @return
     */
    private int factorial(int n) {
        if (n <= 1) {
            return 1;
        }
        return factorial(n - 1) * n;
    }
}
样列二:
八皇后问题

问题描述:将八个皇后放在棋盘上,任何两个皇后都不能互相攻击(即没有任何两个皇后在同一行、同一列或者同一对角线上

二维数组解决
/**
 * 八皇后问题
 * 在8*8的国际象棋的棋盘上摆8个皇后
 * 让8个皇后不能互相攻击,皇后不能同一行同一列,不能同一斜线
 * 计算摆放方法
 * 摆放的位置设置为1
 * 
 * 使用二维数组来解决
 */
public class QueueOperator {

    /**
     * 棋盘的规格
     */
    private static int size = 8;

    //创建一个 8*8的棋盘
    private int[][] checkerboard = new int[size][size];

    /**
     * 计数器
     */
    int count = 0;

    /**
     * 摆放开始
     */
    public void start() {
        put(0);
    }


    /**
     * 摆放位置
     *
     * @param row
     */
    private void put(int row) {
        if (row == 8) {
            // 最后行 放置完毕 打印皇后
            count++;
            System.out.println("打印次数" + count);
            showCheckerboard();
            return;
        }
        // 遍历当前行的所有单元格 以列为单元
        for (int i = 0; i < 8; i++) {
            // 是否能够放置皇后
            if (judge(row, i)) {
                checkerboard[row][i] = 1;
                // 放置下一行
                put(row + 1);
                //当这排列跳出来时,回溯一次,再继续递归
                //没有这段代码的话,上一个皇后放的有问题得时候,
                // 下一行遍历找不到合适的位置,程序就退出了
                //有了这行代码,递归调用得不到结果时,返回上层,清除该位置,移动一下皇后的位置
                checkerboard[row][i] = 0;
            }
        }
    }


    /**
     * 判断拜访在该位置是否可行
     *
     * @param row 行
     * @param col 列
     * @return
     */
    public boolean judge(int row, int col) {
        //第0行随便拜访都是没问题得
        if (row == 0) {
            return true;
        }
        //判断之前的皇后,是否在同一列
        for (int i = 0; i < row; i++) {
            //某行该列是否也摆放了皇后
            if (checkerboard[i][col] == 1) {
                return false;
            }
        }
        //判断是否在同一直线
        //相差一行的情况下,列相差一个位置
        //相差两行的情况下,列相差两个位置
        //所以col - i col + i
        for (int i = 0; i < row; i++) {
            //判断左上
            int left = col - (row - i);
            if (left >= 0) {
                if (checkerboard[i][left] == 1) {
                    return false;
                }
            }
            //判断右上
            int right = col + (row - i);
            if (right < 8) {
                if (checkerboard[i][right] == 1) {
                    return false;
                }
            }
        }

        return true;
    }


    //打印棋盘
    public void showCheckerboard() {
        for (int i = 0; i < checkerboard.length; i++) {
            int[] ints = checkerboard[i];
            for (int j = 0; j < ints.length; j++) {
                System.out.print(" " + ints[j]);
            }
            System.out.println("");
        }
    }

}

数组解决
/**
 * 八皇后问题
 * 在8*8的国际象棋的棋盘上摆8个皇后
 * 让8个皇后不能互相攻击,皇后不能同一行同一列,不能同一斜线
 * 计算摆放方法
 * 摆放的位置设置为1
 * <p>
 * 使用1位数组来解决
 */
public class QueueOperator1 {

    /**
     * 棋盘的规格
     */
    private static int size = 8;


    /**
     * 封装摆放的数据
     */
    private int[] checkerboard = new int[size];

    /**
     * 计数器
     */
    int count = 0;

    /**
     * 摆放开始
     */
    public void start() {
        put(0);
    }


    /**
     * 摆放位置
     *
     * @param row
     */
    private void put(int row) {
        if (row == 8) {
            // 最后行 放置完毕 打印皇后
            count++;
            System.out.println("打印次数" + count);
            showCheckerboard();
            return;
        }
        // 遍历当前行的所有单元格 以列为单元
        for (int i = 0; i < checkerboard.length; i++) {
            // 是否能够放置皇后,不能放置,就跳到下一列
            if (judge(row, i)) {
                //放置皇后
                checkerboard[row] = i;
                // 放置下一行,进入递归调用,直接到row==8才运行完毕
                put(row + 1);
                //找完了checkerboard[row] = i; 下的全部摆法后,跳回当前的层
                //然后判断皇后摆法到下一i 是否可行, 一层层的不断找可以摆放的位置,
                //找到后就跳到下一层,找不到就改变i的值,这一层全部找完后,跳到上一层
                //然后不断的改变i的值,第0层-->第1层-->第2层-->第3层-->...最后一层-->倒数第二层-->...第1层-->第0层,递归完毕
            }
        }
    }


    /**
     * 判断拜访在该位置是否可行
     *
     * @param row 行
     * @param col 列
     * @return
     */
    public boolean judge(int row, int col) {
        //第0行随便拜访都是没问题得
        if (row == 0) {
            return true;
        }
        //判断之前的皇后,是否在同一列
        for (int i = 0; i < row; i++) {
            //col 相同在同行,  相邻两行位置差1个位置,肯定是在斜线上, 差2行,就不能差2个位置,以此类推
            if (checkerboard[i] == col || (row - i) == Math.abs(col - checkerboard[i])) {
                return false;
            }


        }
        return true;
    }


    /**
     * 打印棋盘
     */
    public void showCheckerboard() {
        System.out.println(Arrays.toString(checkerboard));
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值