八皇后问题-回溯法js版

326 阅读1分钟

源码

var queenPlace = []
var count = 0
var printStr = ''

function printQueen() {
    for (var i = 0; i < 8; i++) {
        for (var j = 0; j < 8; j++) {
            if (queenPlace[i] == j) {
                printStr += 'Q '
            } else {
                printStr += '* '
            }
        }
        printStr += '\n'
    }
    console.log(printStr)
    console.log(`----count:${++count}----\n`)
}

// 判断行列位置是否合适
function isOk(row, col) {
    var leftUp = col - 1			// 落点皇后的左上对角线
    var rightUp = col + 1			// 落点皇后的右上对角线

    for (var i = row - 1; i >= 0; i--) {
        if (queenPlace[i] == col) return false				// 同列上的格子有皇后
        if (leftUp >= 0) {
            if (queenPlace[i] == leftUp) return false		// 左上对角线有皇后
        }
        if (rightUp < 8) {
            if (queenPlace[i] == rightUp) return false		// 右上对角线有皇后
        }
        --leftUp
        ++rightUp
    }
    return true
}

function eightQueen(row) {
    if (row == 8) {
        printQueen()
        return
    }
    for (var col = 0; col < 8; col++) {
        if (isOk(row, col)) {
            queenPlace[row] = col
            eightQueen(row + 1)
        }
    }
}

eightQueen(0)

思路分析

判断落点位置的同列(仅搜索上方)是否有其他皇后,如果通过,就搜索落点位置的左上方对角线上是否有其他皇后,如果还通过,继续搜索落点位置的右上方对角线上是否有其他皇后,如果全通过了,就意味着该点位置符合规则。 因为程序在执行过程中是从棋盘左上角逐行执行的,所以只需搜索3个方向即可,而也不用去搜索落点位置的下方、左下角对角线、右下角对角线。水平方向也不用搜索了,因为程序一旦在一行上找到合适的落点位置,会直接去下一行从行头开始搜索。

每颗棋子都是如下图进行搜索:

参考图片