Tail recursion
When a function is called, it creates a stack space in advance and allocates space to the passed parameters. When the function ends and returns the upper-layer function, some local variables need to pop up from the stack and restore to the value before the subfunction is called, and return to the field before the previous function calls the subfunction. If it is tail recursion, the function will also end when the subfunction returns, so there is no need to restore some local variables and directly Delete the stack space of the local variables. Therefore, a tail recursive function does not need to use stacks to provide space for sub-function variables. You can directly use the value of the current variable as the value of the new parameter.
Backtracking
A queens class is used to represent the current Queen layout on the board. The solve_from () function is used to find a solution from the current layout. The overall idea is as follows:
Solve_from (Queens configuration) if the eight-queen layout has been completed print configuration else for each grid not controlled by the Queen {put a queen on the grid in the configuration; solve_from (configuration ); remove the Queen in configuration ;}
The idea of the whole program is to first enter the size of the board. If it is a reasonable input, create a Queens class of this size and use the solve_from () function to find the result, as shown below:
int main() {int board_size;int max_board = 10;print_configuration();cout << "what is the size of the board?" << flush;cin >> board_size;if(board_size < 0 || board_size > max_board)cout << "the size must between 0 and " << max_board << endl;else{Queens configuration(board_size);solve_from(configuration);}return 0;}
In the queens class, the problem to be solved is how to select a Data Structure to store the current Queen layout. Here, a Boolean two-dimensional array is selected to represent the checker. Count records the number of Queens that have been placed, in the order from top to bottom, that is to say, when Count = K, all K rows above have been occupied by the Queen. You can also use the following methods:
- Bool unguarded (INT col) const: whether the col column position of the first row that is not occupied is ruled
- Void insert (INT col): Insert a queen to the col position of the first row not occupied, and count ++
- Void remove (INT col): remove the queen of the bottom line occupied from the col position, and count --
- Bool is_solved () const: returns true if the number of Queens reaches board_size;
The basic data structure of the class is as follows:
const int MAX_BOARD = 30;class Queens {public:int board_size;bool unguarded(int col) const;void insert(int col);void remove(int col);bool is_solved() const;void print();private:int count;//current number of queensbool queen_square[MAX_BOARD][MAX_BOARD];};
Main functions:
Queens: Queens (INT size) {board_size = size; Count = 0; For (int row = 0; row <board_size; ++ row) {for (INT Col = 0; col <board_size; ++ col) {queen_square [row] [col] = false ;}} void Queens: insert (INT col) {queen_square [count ++] [col] = true;} bool Queens: unguarded (INT col) const {bool OK = true; For (INT I = 0; OK & I <count; ++ I) {// check whether there is a queen on the col column. OK =! Queen_square [I] [col] ;}for (INT I = 0; OK & count-I> = 0; ++ I) {// check whether there is queen in the upper left corner. OK =! Queen_square [count-I] [col-I];} For (INT I = 0; count-I> = 0 & COUNT + I <board_size; ++ I) {// OK =! Queen_square [count-I] [col + I];} Return OK ;}
The main method for the eight queens problem is the backtracking method, which can start from a certain State, try to change to the next state, and then start solving the problem from the next state, then restore to the original status and try again.
Backtracking and eight queens