递归就是方法不断的调用方法本身,每次调用时,传入不同的变量
递归每调用一次方法本身,就将方法压入栈中,执行完栈顶的方法后,将结果返回,方法依次出栈,最后全部出栈.递归调用完毕
样列一
阶乘的运算
问题描述:
大于等于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));
}
}