八皇后问题java实现

问题描述
八皇后是基于国际象棋,进行一个小游戏:在一个8 * 8的棋盘上,放置8个皇后(就是8个位置棋子),每个皇后与其他皇后不能在同一行和同一列或者是同一个斜线上,需要寻找摆放位置。
问题分析
1、需要使用一个二维数据array[][] 分别代表皇后放置在第几行,第几列。
2、皇后放置不能越界
3、判断皇后的位置不与其他皇后冲突,即每个皇后坐标不能有相同的横坐标或者是纵坐标,斜线上判断横坐标与横坐标相减绝对值不能等于纵坐标与纵坐标相减的绝对值。
4、从第一行第一列开始排列,利用回溯的思想,进行寻找
代码实现


public class EightQueen {

    /**
     * 申请一维数组,用于保存放置皇后位置
     * 数组的下标数字,代表的是行的位置,数组下标位置的数据代表皇后所在列的位置
     * 例如 queen[1] = 5 代表皇后所在位置为第二行的第6列,
     * 因为是一个皇后标识符,所以使用一维数组,代替二维数组,更加节省空间
     */
    private int[] queen;

    /**
     * 放置皇后主要方法
     * @param n
     */
    public void setQueen(int n){
        queen = new int[n];
        /**
         * 因为数组从0开始,所以
         * 利用-1表示当前行没有放置皇后
         * 初始化皇后信息
         */
        for (int i = 0 ;i < n ;i++){
            queen[i] = -1;
        }
        int r = 0; // 代表行数
        /**
         * 此循环处理,是回溯方法的主要部分
         * 主要的思路是,放置每一行皇后位置后,进行合法性判断
         * 1、判断当前位置是否已经超出棋盘,即是否已经到了最后一列以外
         *    如果当前列已经放置到最后一列都没有合适的,则说明当前摆放不合适,向上一行进行数据挪动依次判断,直到第0行为止
         * 2、判断放置的皇后是否与其他已经放置的皇后冲突,调用冲突判断方法,可查看规则说明
         */
        while (true){
            // 当前行放置皇后位置,比上一次需要往后挪动一个
            queen[r] += 1;
            // 判断当前皇后位置,是否已经越界,未越界情况下,继续判断是否冲突
            if (queen[r] >= n ){
                // 如果已经越界,说明当前行的位置与之前的皇后位置都有冲突,则需要回头挪动上一行的皇后
                if (r>0) {// 需要在回退行大于第0行的情况下,才进行回退,否则第0行的皇后都越界了,说明不需要再进行寻找了
                    queen[r] = -1; // 设置当前行皇后为初始无放置状态
                    r--;// 回退一行
                    continue; // 继续寻找合适位置逻辑
                } else {
                    // 结束循环
                    break;
                }
            }
            /**
             * 如果皇后所在位置,不与之前放置皇后所在位置冲突,则可以寻找下一行的皇后位置
             */
            if (!isConflict(r)){
                // 当前旗子没有冲突,将当前行皇后安放号,准备安放下一行皇后
                r++; // 行向后挪动一位
                if (r >= n){ // 判断向下的行是否已经到了最大行,如果已经是最大行,则说明完成了一次放置,进行回溯处理
                    // 打印当前皇后位置摆放
                    for (int i = 0;i < n;i++){
                        System.out.print(queen[i]+" ");
                    }
                    System.out.println();
                    r--;
                    
                    /**
                     * r-- 操作可将实现回溯查找
                     * 当r -- 操作后,将回到循环开始位置,寻找最后一行是否还有合适位置,如果没有,则前一行进行变化,直到第一行挪动数据,
                     * 如此往返,完成所有行的遍历,寻找所有皇后位置
                     */
                }
            }
            /**
             * 冲突判断未通过,则说明,当前行放置的皇后位置与之前皇后位置冲突
             * 结束本次的判断,进入下一次循环判断,进入下一次后,当前行的皇后位置向后挪动一位,
             * 从而首位相连,便可形成一个完整的回路
             */
        }
    }

    /**
     * 判断第k个皇后是否与之前的皇后冲突,冲突返回true,不冲突返回false
     * 判断规则,如果当前下标对应的数据与之前下标对应的数据相等,则说明皇后在同一列,冲突
     * 如果|行-行| = |列-列| 用绝对值相比结果相同,则说明两个皇后在斜着的同一条线上,冲突
     * 否则返回false不冲突
     */
    public boolean isConflict(int k){
        for (int i = k -1;i>-1;i--){
            if (queen[k] == queen[i] || Math.abs(queen[k]-queen[i])==Math.abs(k - i)){
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        EightQueen eightQueen = new EightQueen();
        eightQueen.setQueen(8);
    }

}

你可能感兴趣的:(java数据结构和算法学习,java,算法,开发语言)