能否在不使用goto语句与递归的情况下实现Knuth的N皇后Algorithm B?
关于无goto/递归实现Knuth N皇后Algorithm B的问题
我掌握N皇后问题的基础递归解法,目前正在研究并实现Knuth提出的「Algorithm B(基础回溯法)」,以此深入学习回溯技术。该算法在《计算机程序设计艺术》第4B卷分册5的7.2.2节「回溯编程」中有描述。
我已经写出了一个基于goto的C语言实现,直接对应Knuth的算法描述(仅针对零索引数组做了少量修改),运行正常:
// x 和 a 都是长度为 N 的数组,b 和 c 是长度为 2*N-1 的数组 // 调用该函数前需确保这些数组已被清零 static void queens(int x[], bool a[], bool b[], bool c[], const size_t n) { size_t col, row = 0; advance_row: if (row >= n) { // 例如 n=4 时输出 "a2 b4 c1 d3" print_positions(x, n); goto backtrack; } col = 0; try_column: if (!a[col] && !b[col+row] && !c[col-row+n-1]) { a[col] = true; b[col+row] = true; c[col-row+n-1] = true; x[row] = col; row++; goto advance_row; } try_again: if (col < n-1) { col++; goto try_column; } backtrack: if (row != 0) { --row; col = x[row]; c[col-row+n-1] = false; b[col+row] = false; a[col] = false; goto try_again; } }
我发现这个算法的控制流图(CFG)是不可约的,因此认为仅用while循环、for循环和if语句可能无法实现,但还是做了尝试。我推测需要用变量保存状态,但不知道该如何表示这个控制流图。
我尝试替换部分goto语句写出了一个版本,但存在错误:当n=4时,它能正确打印前2个解,但会额外输出58个错误解:
static void queens(int x[], bool a[], bool b[], bool c[], const size_t n) { for (size_t row = 0, col = 0; ; col++) { while (!a[col] && !b[col+row] && !c[col-row+n-1]) { a[col] = true; b[col+row] = true; c[col-row+n-1] = true; x[row] = col; row++; if (row >= n) { print_positions(x, n); goto backtrack; } col = 0; } if (col < n - 1) { continue; } backtrack: if (row == 0) break; else do { --row; col = x[row]; c[col-row+n-1] = false; b[col+row] = false; a[col] = false; if (col < n - 1) { break; } } while (row != 0); } }
请问是否可以在不使用goto语句或递归的情况下实现该算法?
内容的提问来源于stack exchange,提问作者MaroonSphinx
相关产品推荐
相关产品推荐

