一、递归
1.定义
程序调用自身的编程技巧称为递归( recursion)。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。
递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
2.解决什么问题?
① 各种数学问题,例如:8皇后问题,汉诺塔,阶乘问题,迷宫问题,球和篮子问题。
② 各种算法中也会使用到递归,例如:快排,归并排序,二分查找,分治算法等。
③ 将用栈解决的问题——>递归代码比较简洁。
3.递归运用——迷宫问题
4.递归运用——八皇后问题
问题介绍 : 该问题是国际西洋棋棋手马克斯.贝瑟尔于1848年提出。在8*8格的国际象棋上摆放八个皇后,使其不能互相攻击。即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
package com.ljf.system.recursion;
/**
* 8皇后问题
* @author 吕继帆
* @since 2021/12/14/10:16
*/
public class Queen8 {
public int maxQueen;
public int[] array;
public int count;
public Queen8(int maxQueen) {
this.maxQueen = maxQueen;
this.array = new int[maxQueen];
this.count = 0;
}
public static void main(String[] args) {
Queen8 queen8 = new Queen8(8);
queen8.check(0);
System.out.println("总共有:" + queen8.count + "种方法");
}
// 判断第n个皇后,当判断n皇后在第i列没问题后,就递归调用n+1皇后
public void check(int n) {
if (n == maxQueen) {
for (int temp : array) {
System.out.print(temp);
}
count ++;
System.out.println();
return;
}
for (int i = 0; i < maxQueen; i++) {
array[n] = i;
if (judge(n)) {
check(n + 1);
}
}
}
// 判断n皇后的当前列是否和之前几个皇后冲突
// 难点在于判断皇后是否在同一斜线上。当行数差等于列数差时就在同一直线上
public boolean judge(int n) {
for (int i = 0; i < n; i++) {
if (array[i] == array[n] || (n-i == Math.abs(array[n]-array[i]))) {
return false;
}
}
return true;
}
}