关于递归
简单来说,递归就是函数的重复调用。每一次函数调用都存储在栈中。当栈顶的函数执行完毕,才会执行栈中的下一个元素。
递归的几个注意点:
- 明白递归的函数正在进行什么操作,它做了什么事情?
- 在递归中必须要设置结束条件、明确结束条件,并且逐步靠近结束条件。不然会形成无限的递归。
- 递归就是有去(递去)有回(归来)。
- 相同重复逻辑,缩小问题的规模。
参考文章
递归入门
阶乘
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();
}
}
最后,如果这篇文章对你有帮助的话,不妨点个收藏再走哦!
⭐码字不易,求个关注⭐
⭐点个收藏不迷路哦~⭐