递归解决八皇后问题-小昝

来源:互联网 发布:informix数据库操作 编辑:程序博客网 时间:2024/04/30 12:50

引言
由于大学课堂中数据结构中并没有讲一些常见的算法,只是讲的比较简单的定义。所以拿出来暑假时间去研究经典的算法。本文章是研究的八皇后问题。八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。
思路
之前听到过很多次“八皇后问题”,但是都没有仔细研究(好吧,我承认智商不够,精力不足),这次仔细研究了这个问题。首先结合递归的定义,可以分解成相似结构的相同小问题,而这个题因为 每一行 每一列只能能有一个皇后,所以8行可以分解为7行,7行可以分解为6行 ……。这样我们从第一个行开始,如果符合条件,递归调用(raw+1,n,chess);如果raw能到8,则说明是符合的,则打印出来。
说起来比较抽象,上代码看一下:

C语言描述

//山东科技大学小昝#include <stdio.h>#include <math.h>//count 记录一共有多少种符合情况。int count = 0;int notDanger(int row,int column,int (*chess)[8]){    int i,j;    for(i=0;i<row;i++){        for(j=0;j<8;j++){            if(chess[i][j]==1){                if(j == column){                    return 0;                }                if(abs(i-row) == abs(j-column)){                    return 0;                }            }        }    }    return 1;}void EightQueen(int row ,int n ,int (*chess)[8]){    int i,j,chess2[8][8];    for(i=0;i<8;i++){        for(j=0;j<8;j++){            chess2[i][j] = chess[i][j];        }    }    if(row == 8){        printf("第 %d 次\n",count+1);        for( i = 0;i <8;i++){            for( j =0 ;j<8;j++){                printf("%d ",*(*(chess2+i)+j));            }            printf("\n");        }        printf("\n");        count++;    }else{        for(i = 0;i<n;i++){            if(notDanger(row,i,chess)){                for(j = 0;j<8;j++){                    *(*(chess2+row)+j)=0;                }                *(*(chess2+row)+i)=1;                EightQueen(row+1,n,chess2);            }        }    }}int main(){    int chess[8][8],i,j;    for(i=0;i<8;i++){        for(j=0;j<8;j++){            chess[i][j]=0;        }    }    EightQueen(0,8,chess);    printf("一共 %d 种情况!\n",count);    return 0;}

JAVA描述

package alizantest;//山东科技大学小昝public class EightQueen {    static int count = 0;    private static boolean notdanger(int row, int column, int[][] chess) {        // TODO Auto-generated method stub        int i, j;        for (i = 0; i < row; i++) {            for (j = 0; j < 8; j++) {                if (chess[i][j] == 1) {                    if (j == column) {                        return false;                    }                    if (Math.abs(row - i) == Math.abs(column - j)) {                        return false;                    }                }            }        }        return true;    }    private static void EightQueen(int row, int column, int[][] chess) {        int i, j;        int[][] chess2 = new int[8][8];        for (i = 0; i < 8; i++) {            for (j = 0; j < 8; j++) {                chess2[i][j] = chess[i][j];            }        }        if (row == 8) {            System.out.println("第" + count + 1 + "个");            for (i = 0; i < 8; i++) {                for (j = 0; j < 8; j++) {                    System.out.print(chess2[i][j] + " ");                }                System.out.println();            }            System.out.println();            count++;        } else {            for (i = 0; i < column; i++) {                if (notdanger(row, i, chess)) {                    for (j = 0; j < 8; j++) {                        chess2[row][j] = 0;                    }                    chess2[row][i] = 1;                    EightQueen(row + 1, column, chess2);                }            }        }    }    public static void main(String[] args) {        int[][] chess = new int[8][8];        int i, j;        for (i = 0; i < 8; i++) {            for (j = 0; j < 8; j++) {                chess[i][j] = 0;            }        }        EightQueen(0, 8, chess);        System.out.println("一共有" + count + "种");    }}

在用java写八皇后的时候犯得一个大的错误,导致费了半小时调试出来的。就是混用了chess与chess2,导致结果不对。所以,我们做事的时候要细心,一定细心!
八皇后问题比较抽象,是经典的算法,多多思考。希望有一天我们都能把递归算法用的炉火存青!

原创粉丝点击