用树可以形象直观地描述回溯法。《算法设计技巧与分析》 #ifndef __QUEENS_H__ #define __QUEENS_H__ class Queens { public: Queens(int nQueens); ~Queens(); bool Setout(); // 摆放皇后 inline int* GetAnswer(){return m_pos;} inline bool isLegal(int row, int col) // 合法性 { return (row == m_nQueens-1) && isPartSolution(row, col); } inline bool isPartSolution(int row, int col) //在第row行的第col列摆放 { // 判断当前的位置与原先排好的位置没有冲突 int i, j; bool flag = true; for (i = 0; i < row; i++) { j = m_pos[i]; if (col == j || row-i == col-j || row-i == j-col) { flag = false; break; } } return flag; } protected: int m_nQueens; // 皇后数目 int* m_pos; }; #endif #include "queens.h" #include <assert.h> #include <string.h> // constructor Queens::Queens(int nQueens) { m_nQueens = nQueens; m_pos = new int[m_nQueens]; assert(m_pos); } // destructor Queens::~Queens() { if (m_pos != 0) { delete[] m_pos; } } // 摆放皇后 bool Queens::Setout() { // 设置所有位置为空,不摆放皇后 /*memset(m_pos, 0, sizeof(int) * m_nQueens);*/ int i = 0; for (i = 0; i < m_nQueens; i++) { m_pos[i] = -1; } bool flag = false; // 标记是否找到合法的解 int k = 0; // 第k行 while (k >= 0) { while (m_pos[k] < m_nQueens-1) // m_pos[k]的最大值为m_nQueens-1 { // 当m_pos[k]取到最大值后,仍然没有得到合法解时,跳出内循环进行回溯 m_pos[k] += 1; if (isLegal(k, m_pos[k])) { flag = true; break; } else if (isPartSolution(k, m_pos[k])) { k++; } } if (flag) { break; } else { // 回溯 m_pos[k] = -1; // 清楚当前层 k--; } } return flag; } #include <iostream> #include "queens.h" using namespace std; int main() { int const nQueens = 10; Queens queens(nQueens); if (queens.Setout()) { int* answer = queens.GetAnswer(); int i, j; for (i = 0; i<nQueens; i++) { for (j = 0; j < nQueens; j++) { if (j == answer[i]) { cout << "+" << " "; } else { cout << "-" << " "; } } cout << endl; } } else { cout << "no solution" << endl; } return 0; }