n皇后问题详解(附完整代码)——java

n皇后问题

java现在已成为最热门的编程语言,我自己也在学习java,在学习java的过程中,最难的应该莫过于算法了。今天来玩一下n皇后问题,也算是记录自己在算法学习中的成长足迹,通过博客可以促进博主与阅读者的共同进步,结交更多志同道合的朋友。特此分享给大家,本人见识有限,写的博客难免有错误或者疏忽的地方,还望各位大佬指点,在此表示感激不尽。那,,,我们开始吧。那今天我们就来分析一下著名的n皇后问题,用深度搜索(dfs)来解答。
用java语言
n皇后问题详解(附完整代码)——java_第1张图片
详述
主要涵盖深搜、递归、剪枝、回溯的算法思想
框架
1. 用自定义dfs函数进行深搜等操作
2. 自定义check函数作为在深搜过程中判断条件是否成立
3. main函数调用运行
解析

char res[][] 存储正确的答案
row 深搜的列数

res[][]初始状态
在这里插入图片描述
dfs中按一列一列的进行,正解时每一列就会存在一个皇后。
n皇后问题详解(附完整代码)——java_第2张图片
1生4,4生16…(由四重递归模拟)就构成了一棵树。
每一次递归时,此方格格放了可能非正解,就排除,提前判断check(),符合条件递归往下走。并给此方格标记‘W’,不符合在此列换下次个格子,若都不符合此列递归完成到前一列状态,在判断,往往复复、直至得到正解输出继续未完成任务(此不是唯一解,所以还要继续,找到所有的解,若为唯一解,找到后用exit(0)退出程序)
每一次递归,如果不是正解,数组会被改变,所以不成立时用回溯回到上一个状态,

for (int i=0;i<n;i++){
            if(check(res,i,row)){
                res[i][row]='W';
                dfs(res,n,row+1);
                res[i][row]='*';//回溯
            }
            

check(剪枝)中就作为判断是否符合条件。此格纵横斜均无皇后
纵:res[x][i]‘W’ 有返回false
横:res[i][y]
‘W’ 有返回false
斜:斜向是 i+jx+y 正向
i-j
x-y 反向
用check可判断是否符合条件。

   if(res[x][i]=='W')return false;
            if(res[i][y]=='W')return false;

            for(int j=0;j<res.length;j++){
                if(i+j==x+y&&res[i][j]=='W')return false;
                if (i-j==x-y&&res[i][j]=='W')return false;

代码片段
dfs()代码

static void dfs(char res[][],int n,int row){
        if(row==n){
            account++;
            System.out.println();
            for(int i=0;i<n;i++){
                for(int j=0;j<n;j++){
                    System.out.print(res[i][j]+"  ");
                }
                System.out.println();
            }
            return;
        }
        for (int i=0;i<n;i++){
            if(check(res,i,row)){
                res[i][row]='W';
                dfs(res,n,row+1);
                res[i][row]='*';
            }
        }
    }

check()判断代码

   static boolean check(char res[][],int x,int y){
        for(int i=0;i<res.length;i++){
            if(res[x][i]=='W')return false;
            if(res[i][y]=='W')return false;

            for(int j=0;j<res.length;j++){
                if(i+j==x+y&&res[i][j]=='W')return false;
                if (i-j==x-y&&res[i][j]=='W')return false;
            }
        }
        return true;
    }

代码(亲测有效)


import java.util.Scanner;

public class NQueen{  
    public static void main(String[] args) {			//主函数
        Scanner scanner=new Scanner(System.in);
        int n=scanner.nextInt();			//输入函数
char res[][]=new char[n][n];				//对数组初始化
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
               res[i][j]='*';
            }
        }
        dfs(res,n,0);			//调用深搜函数
        System.out.print("符合条件的个数为:");
        System.out.println(account);
    }
    static int account=0;
    static void dfs(char res[][],int n,int row){
        if(row==n){
            account++;
            System.out.println();
            for(int i=0;i<n;i++){
                for(int j=0;j<n;j++){
                    System.out.print(res[i][j]+"  ");
                }
                System.out.println();
            }
            return;
        }
        for (int i=0;i<n;i++){
            if(check(res,i,row)){
                res[i][row]='W';
                dfs(res,n,row+1);
                res[i][row]='*';
            }
        }
    }
    static boolean check(char res[][],int x,int y){
        for(int i=0;i<res.length;i++){
            if(res[x][i]=='W')return false;
            if(res[i][y]=='W')return false;

            for(int j=0;j<res.length;j++){
                if(i+j==x+y&&res[i][j]=='W')return false;
                if (i-j==x-y&&res[i][j]=='W')return false;
            }
        }
        return true;
    }
}

n皇后问题详解(附完整代码)——java_第3张图片

你可能感兴趣的:(算法)