/**
* 递归规则:
* - 执行一个方法时,就创建一个新的受保护的独立空间(栈空间)
* - 方法的局部变量是独立的,不会相互影响, 比如n变量如果方法中使用的是引用类型变量(比如数组),就会共享该引用类型的数据.
* - 递归必须向退出递归的条件逼近,否则就是无限递归,出现StackOverflowError)
* - 当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕。
*/
public class Factorial {
//阶乘
public static int factorial(int n) {
if (n == 1) {
return 1;
} else {
return factorial(n - 1) * n;
}
}
//递归打印
public static void test(int n) {
if (n > 2) {
test(n - 1);
}
System.out.println("n=" + n);
}
public static void main(String[] args) {
test(4);
//n=2
//n=3
//n=4
System.out.println("factorial(2) = " + factorial(2));
}
}
package stu;
/**
* 递归回溯--迷宫问题
*/
public class MiGong {
/**
* 地图,1表示墙,0表示该点没走过
* 走迷宫方法下->右->上->左
*/
public static int[][] getMap(){
int[][] map = new int[8][7];
int row = map.length;//行数
int col = map[0].length;//列数
for (int i = 0; i < row; i++) {
map[i][0] = 1;
map[i][col-1] = 1;
}
for (int i = 0; i < col; i++) {
map[0][i] = 1;
map[row-1][i] = 1;
}
return map;
}
public static void showMap(int[][] map){
System.out.println("------map-----");
int row = map.length;
int col = map[0].length;
//打印行号
for (int i = 0; i < col; i++) {
if (i==0){
System.out.print("\t"+i+"\t");
} else{
System.out.print(i+"\t");
}
}
System.out.println();
for (int i = 0; i < row; i++) {
//打印列号
System.out.print(i+"\t");
for (int j = 0; j < col; j++) {
System.out.print(console(map[i][j])+"\t");
}
System.out.println();
}
System.out.println("--------------");
}
public static String console(int i) {
if (i == 0) {//未走的点
return "○";
} else if (i == 1) {//墙
return "♟";
} else if (i == 2) {//已走的点
return "☻";
} else if (i == 3) {//死路
return "×";
}
return "×";
}
/**
* 寻路 终点[6][5]
* 2表示通路走过,3表示该点走过又一次走,变死路了,走不通
* @param map
* @param i 横
* @param j 枞
* @return
*/
public static boolean setWay(int[][] map,int i,int j){
if (map[6][5]==2){
return true;
}else {
if (map[i][j]==0){
map[i][j]=2;
if (setWay(map,i+1,j)){//向下
return true;
}else if (setWay(map,i,j+1)){//向右
return true;
}else if (setWay(map,i-1,j)){//向上
return true;
}else if (setWay(map,i,j-1)){//向左
return true;
}else {
map[i][j]=3;
return false;
}
}else { //遇到墙,或死路,或已经走过
return false;
}
}
}
public static void main(String[] args){
int[][] map = getMap();
showMap(map);
//从[1][1]做起点
setWay(map,1,1);
showMap(map);
// 0 1 2 3 4 5 6
//0 ♟ ♟ ♟ ♟ ♟ ♟ ♟
//1 ♟ ☻ ○ ○ ○ ○ ♟
//2 ♟ ☻ ○ ○ ○ ○ ♟
//3 ♟ ☻ ○ ○ ○ ○ ♟
//4 ♟ ☻ ○ ○ ○ ○ ♟
//5 ♟ ☻ ○ ○ ○ ○ ♟
//6 ♟ ☻ ☻ ☻ ☻ ☻ ♟
//7 ♟ ♟ ♟ ♟ ♟ ♟ ♟
}
}
package stu;
/**
* 八皇后问题:
* 在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,
* 即:任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
* 八皇后问题算法思路分析:
* 1.第一个皇后先放第一行第一列
* 2.第二个皇后放在第二行第一列、然后判断是否OK, 如果不OK,继续放在第二列、第三列、依次把所有列都放完,找到一个合适
* 3.继续第三个皇后,还是第一列、第二列……直到第8个皇后也能放在一个不冲突的位置,算是找到了一个正确解
* 4.当得到一个正确解时,在栈回退到上一个栈时,就会开始回溯,即将第一个皇后,放到第一列的所有正确解,全部得到.
* 5.然后回头继续第一个皇后放第二列,后面继续循环执行 1,2,3,4的步骤
*/
public class Queens8 {
private int MAX = 8;
private static int count = 0;
private static int judgeCount = 0;
//第0行的列的位置,默认【0,0】
private int firstCol = 0;
//对应arr下标表示第几行,即第几个皇后
//arr[i] = val , val 表示第i个皇后,放在第i行的第val列,皇后从0到7共8个,行与列也是从0开始
int[] arr = new int[MAX];
private boolean queens8 = false;
private boolean queens82 = false;
public Queens8() {
queens8 = true;
new Queens().check(0);
}
public Queens8(int firstCol) {
queens82 = true;
this.firstCol = firstCol;
new Queens().checkByFirstCol(0);
}
private class Queens {
//第n个皇后
private void check(int n) {
//1种方法输出一次
if (n == MAX) {
console();
return;
}
for (int i = 0; i < MAX; i++) {
arr[n] = i;
if (judge(n)) {
check(n + 1);
}
}
}
//按照第n个皇后在第0行的列的位置
private void checkByFirstCol(int n) {
//1种方法输出一次
if (n == MAX) {
console();
return;
}
for (int i = 0; i < MAX; i++) {
if (n == 0 && i > firstCol) {
break;
}
if (n == 0 && i != firstCol) {
continue;
}
arr[n] = i;
if (judge(n)) {
check(n + 1);
}
}
}
//判断是否冲突
//第n个皇后
private boolean judge(int n) {
judgeCount++;
for (int i = 0; i < n; i++) {
//第n个是否与前面的n-1在同一列
//第n个是否与第i个是否在同一斜线(两个的行差等于列差)
if (arr[n] == arr[i] || Math.abs(n - i) == Math.abs(arr[n] - arr[i])) {
return false;
}
}
return true;
}
}
//输出位置
private void console() {
count++;
for (int i : arr) {
System.out.print(i + "\t");
}
System.out.println();
}
private void print() {
if (queens8){
System.out.println("共有" + count + "种解法");
}else {
System.out.println("第0列的皇后放在第"+firstCol+"列,有" + count + "种解法");
}
System.out.println("判断冲突次数:" + judgeCount);
}
public static void main(String[] args) {
new Queens8().print();
new Queens8(0).print();
new Queens8(1).print();
}
//0 4 7 5 2 6 1 3
//0 5 7 2 6 3 1 4
//0 6 3 5 7 1 4 2
//0 6 4 7 1 3 5 2
//1 3 5 7 2 0 6 4
//1 4 6 0 2 7 5 3
//1 4 6 3 0 7 5 2
//1 5 0 6 3 7 2 4
//1 5 7 2 0 3 6 4
//1 6 2 5 7 4 0 3
//1 6 4 7 0 3 5 2
//1 7 5 0 2 4 6 3
//2 0 6 4 7 1 3 5
//2 4 1 7 0 6 3 5
//2 4 1 7 5 3 6 0
//2 4 6 0 3 1 7 5
//2 4 7 3 0 6 1 5
//2 5 1 4 7 0 6 3
//2 5 1 6 0 3 7 4
//2 5 1 6 4 0 7 3
//2 5 3 0 7 4 6 1
//2 5 3 1 7 4 6 0
//2 5 7 0 3 6 4 1
//2 5 7 0 4 6 1 3
//2 5 7 1 3 0 6 4
//2 6 1 7 4 0 3 5
//2 6 1 7 5 3 0 4
//2 7 3 6 0 5 1 4
//3 0 4 7 1 6 2 5
//3 0 4 7 5 2 6 1
//3 1 4 7 5 0 2 6
//3 1 6 2 5 7 0 4
//3 1 6 2 5 7 4 0
//3 1 6 4 0 7 5 2
//3 1 7 4 6 0 2 5
//3 1 7 5 0 2 4 6
//3 5 0 4 1 7 2 6
//3 5 7 1 6 0 2 4
//3 5 7 2 0 6 4 1
//3 6 0 7 4 1 5 2
//3 6 2 7 1 4 0 5
//3 6 4 1 5 0 2 7
//3 6 4 2 0 5 7 1
//3 7 0 2 5 1 6 4
//3 7 0 4 6 1 5 2
//3 7 4 2 0 6 1 5
//4 0 3 5 7 1 6 2
//4 0 7 3 1 6 2 5
//4 0 7 5 2 6 1 3
//4 1 3 5 7 2 0 6
//4 1 3 6 2 7 5 0
//4 1 5 0 6 3 7 2
//4 1 7 0 3 6 2 5
//4 2 0 5 7 1 3 6
//4 2 0 6 1 7 5 3
//4 2 7 3 6 0 5 1
//4 6 0 2 7 5 3 1
//4 6 0 3 1 7 5 2
//4 6 1 3 7 0 2 5
//4 6 1 5 2 0 3 7
//4 6 1 5 2 0 7 3
//4 6 3 0 2 7 5 1
//4 7 3 0 2 5 1 6
//4 7 3 0 6 1 5 2
//5 0 4 1 7 2 6 3
//5 1 6 0 2 4 7 3
//5 1 6 0 3 7 4 2
//5 2 0 6 4 7 1 3
//5 2 0 7 3 1 6 4
//5 2 0 7 4 1 3 6
//5 2 4 6 0 3 1 7
//5 2 4 7 0 3 1 6
//5 2 6 1 3 7 0 4
//5 2 6 1 7 4 0 3
//5 2 6 3 0 7 1 4
//5 3 0 4 7 1 6 2
//5 3 1 7 4 6 0 2
//5 3 6 0 2 4 1 7
//5 3 6 0 7 1 4 2
//5 7 1 3 0 6 4 2
//6 0 2 7 5 3 1 4
//6 1 3 0 7 4 2 5
//6 1 5 2 0 3 7 4
//6 2 0 5 7 4 1 3
//6 2 7 1 4 0 5 3
//6 3 1 4 7 0 2 5
//6 3 1 7 5 0 2 4
//6 4 2 0 5 7 1 3
//7 1 3 0 6 4 2 5
//7 1 4 2 0 6 3 5
//7 2 0 5 1 4 6 3
//7 3 0 2 5 1 6 4
//共有92种解法
//判断冲突次数:15720
//0 4 7 5 2 6 1 3
//0 5 7 2 6 3 1 4
//0 6 3 5 7 1 4 2
//0 6 4 7 1 3 5 2
//第0列的皇后放在第0列,有96种解法
//判断冲突次数:17505
//1 3 5 7 2 0 6 4
//1 4 6 0 2 7 5 3
//1 4 6 3 0 7 5 2
//1 5 0 6 3 7 2 4
//1 5 7 2 0 3 6 4
//1 6 2 5 7 4 0 3
//1 6 4 7 0 3 5 2
//1 7 5 0 2 4 6 3
//第0列的皇后放在第1列,有104种解法
//判断冲突次数:19562
}