Problem Description:
This week's data structure job requires a program to judge the case of all Queens entered as N, and the queen is roughly a lattice of all the different rows and diagonals on a n*n board .
Clues to the use of the book to solve the maze of the backtracking method, that is, to use a stack to save the current satisfaction of the Queen, if not continue to backtrack
Implemented with C language
Code:
1, File BetterQueen.h
It mainly defines the data structures and function interfaces to be used by the program.
#ifndef betterqueen_h_included#define betterqueen_h_included#include <stdio.h> #include "BetterQueen.h" # Define MAXSIZE 21/* Because the topic requires no more than 20, because at the beginning of the stack a non-existent board of the Queen (as a sign of the loop end), so the maximum length of the stack is 21 *//*********************************** Defines the "queen" placed lattice type row indicates the coordinates of the row in a Chessboard column (in a 4*4 checkerboard, rows and columns are counted from 0) next_ Column coordinates of the next possible queen (in a 4*4 checkerboard (next_column>=0 && next_column<=n-1)) *************************** /typedef struct{int row; int column; int next_column;} cell;/******************************************************* defines the stack that holds the "queen" It is a key data structure for solving this problem when and only if the next_ of the top element of the current stack When the column coordinates are valid (that is, the grid coordinates in the two-dimensional array of the checkerboard are not-1 o'clock), the next queen of the Next_column flag can enter the stack *********************************************** /typedef struct{Cell queen[maxsize]; int top;} queenstack;/******************************************************* Defines a chain stack that holds the checkerboard state (that is, the values of all the elements in a two-dimensional array) if and only if the two-dimensional array values need to be modified before the current two-dimensional array values are stored in the chain stack (the need to modify the checkerboard state refers to the Queen's stack), you need to modify the current two-dimensional array To make sure that the next queen is not the same as the current stack (queen stack) queen different rows, columns, and different diagonals) when and only if there is Queen retreat (queen Stack), the stack top element in the Checkerboard state stack is returned to the two-dimensional array *******************************************************/typedef struct chessboardstack{ int* data; struct chessboardstack* Next;} chessboardnode;/******************************************************* Initialize Queen stack function ******************************* /queenstack* Init_queen_stack () {queenstack* qs= (queenstack*) malloc (sizeof (queenstack)); qs->top=-1; return QS;} /******************************************************* initialization of the Checkerboard State stack function ********************************************* /chessboardnode* Init_chessboard_stack () {chessboardnode* cbs= (chessboardnode*) malloc (sizeof ( Chessboardnode)); cbs->data=null; cbs->next=null; return CBS;} /******************************************************* Queen into the stack function after the Next_column value is set to 1 (for the next queen to start from scratch) *************** /void Push_queen (queenstack* qs,int r,int c) {+ + (qs->top); qs->queen[qs->top].row=r; qs->queen[qs->top].column=c; Qs->queen[qs->top].next_column=-1;} /******************************************************* judge whether the Queen stack is empty ********************************************** /int queen_stack_is_empty (queenstack* Qs) {return qs->top==-1;} /******************************************************* print a Queen's arrangement ********************************************** /void Print_result (queenstack* qs,int n) {int i,j; for (i=1;i<=n;i++) {for (j=0;j<n;j++) {if (j!=qs->queen[i].column) prin TF ("%d", j+1); else printf (""); } printf ("\ n"); } printf ("\ n");} /******************************************************* out of the stack a queen ************************************************* /void Pop_queen (queenstack* qs) {qs->top--;} /******************************************************* current board state into the stack *********************************************** /void Push_chessboard (chessboardnode* cbs,int* cb,int N) {Chessboardnode* new_node= (chessboardnode*) malloc (sizeof (Chessboardnode)); New_node->data= (int*) malloc (sizeof (int) * (n*n)); int* p=new_node->data; while (p<new_node->data+n*n) *p++=*cb++; new_node->next=cbs->next; Cbs->next=new_node;} /******************************************************* the state of the board state out of the stack when the last queen was restored ************************************** /void Pop_chessboard (chessboardnode* cbs,int* cb,int N) {if (cbs->next==null) return; int* p=cbs->next->data; while (p<cbs->next->data+n*n) *cb++=*p++; chessboardnode* dn=cbs->next; cbs->next=dn->next; Free (DN);} /******************************************************* Modify the Checkerboard state so that the next queen satisfies the different ranks and diagonals of the previous Queen ************************** /void updata_chessboard (int n,int (*chessboard) [N],int r,int c) {int i,j; Chessboard[r][c]=-1; for (i=0;i<n;i++) {chessboard[r][i]=-1; Chessboard[i][c]=-1; } for (i=0; i<n; i++) for (j=0; j<n; J + +) {if (r!=i && c!=j) if (double) (r-i)/(double) (c j) ==-1 | | (double) (r-i)/(double) (c-j) ==1) chessboard[i][j]=-1; }}/******************************************************* destroys Queen's stack ************************************************ /void destroy_queen_stack (queenstack* Qs) {free (QS);} /******************************************************* Destroy the board state stack ************************************************ /void Destroy_chessboard_stack (chessboardnode* CBS) {chessboardnode* p; while (cbs->next!=null) {p=cbs->next; Free (CBS); Cbs=p; } free (CBS);} #endif//betterqueen_h_included
2, File Main.c
Implementation of the N solution of the input corresponding to all queens permutation
/** Copyright (c) 2014, College of Computer and Control engineering, Yantai University * All rights reserved.* file name: main.cpp && betterqueen.h* Author: He Xiaolo * Completion Date: 201 6 April 16 * Version number: v1.0** problem description: Solve the Queen of the number of inputs n the Queen is roughly the same as all the different rows and diagonals on a n*n board. * * #include <stdio.h> #include & lt;stdlib.h> #include <stdio.h> #include "BetterQueen.h" void Queen (int n); int main () {printf ("please input the N Umber of Queens: "); int numofqueens; scanf ("%d", &numofqueens); /* There is no case of Queen 2, 3, negative value is more ridiculous */if ((numofqueens>1 && numofqueens<4) | | numofqueens<0) {printf ( "Input error!"); Exit (0); } queen (Numofqueens); return 0;} /******************************************************* to solve the "queen" may arrange the function of the general idea: 1, a "queen" is not in the board to press into the Queen's Stack, in order to abort the cycle 2, The loop is executed when the stack is not empty: (1) If the row value of the top element of the stack is n-1 (row from 0~n-1, a total of n Queens), indicating that a possible queen permutation has been found, output this set of results. And after the output is out of the stack a queen, in order to traverse the possible situation (2) if (1) does not have found a possible queen permutation, then from the top element of the current stack to locate the next Queen's Row, column values, When the row and column values are found, the Queen is pressed into the stack against the current state of the Board (the values of each element in the two-dimensional array). When the value of a new queen meets the requirements, before pressing into the stack (queen stack), first modify the Next_column value of the Queen in the top queen to the next queen, and thenThe Queen presses into the stack; before modifying the Checkerboard state (the checkerboard state is to make some of the values in the two-dimensional array-1, in order for the next queen to satisfy the different rows and diagonals of the previous queen), the current checkerboard state is pressed into the stack and then the Checkerboard State is modified. Jovin Queen all possible row and column values do not meet the requirements, it means that the previous Queen does not meet the requirements, perform the fallback (queen Stack) operation, and restore the state of the pre-modified chessboard. (The stack will abort the loop when the Next_column value of the Queen, which is pressed into the stack in step 1, means that all possible cases have been traversed) *******************************************************/ void Queen (const int n) {int chessboard[n][n];/* Create checkerboard two-dimensional array corresponding to Queen's number */int *p=*chessboard; /* Initialize the checkerboard so that all values are 0 (0 means that the position can be placed in the Queen,-1 means it cannot be placed) */while (p<*chessboard+n*n) *p++=0; Queenstack* Qs=init_queen_stack (); chessboardnode* Cbs=init_chessboard_stack (); Push_queen (qs,-1,-1); /* Start the stack with a non-existent queen on the Board (as a sign of the loop end) */int flag,count_of_queen=0; int next_queen_row,next_queen_column,current_queen_next_column; while (!queen_stack_is_empty (QS)) {if (qs->queen[qs->top].row==n-1) {count_of_queen++; Print_result (Qs,n); Pop_queen (QS); Pop_chessboard (Cbs,*chessboard,n); } flag=0; Current_queen_next_column=qs->queen[qs->top].Next_column; next_queen_row=qs->queen[qs->top].row+1; while (current_queen_next_column<n-1 && flag==0) {Next_queen_column=++current_queen_next_co Lumn; if (chessboard[next_queen_row][next_queen_column]==0) flag=1; } if (flag==1) {qs->queen[qs->top].next_column=current_queen_next_column; Push_queen (Qs,next_queen_row,next_queen_column); Push_chessboard (Cbs,*chessboard,n); Updata_chessboard (N,chessboard,next_queen_row,next_queen_column); } else {Pop_queen (QS); Pop_chessboard (Cbs,*chessboard,n); }} printf ("The Count of Queens is:%d\n", Count_of_queen); Destroy_queen_stack (QS); Destroy_chessboard_stack (CBS);}
Operation Result:
1, the input is 4 is the Queen's arrangement
2, enter the arrangement of the Queen 8 o'clock (only show part)
Summary:
It's done.
In the beginning to write a C + + implementation of the version, but really tired when the completion of the idea is not very clear, the next day debugging two hours to run
Then look at the program, completely impatient to read, too miscellaneous, the definition of the class is also a mess, and then want to write a clean point C, some operations encapsulated in the function, do not want to use the class
Re-write, the idea is very clear, 1.1-point side of the test writing, not like the first time to write a breath, and finally quickly debugged
Backtracking, sounds good, but the feeling still does not grasp the connotation, because it is referring to the book to solve the maze of ideas written, so many ideas are still in the book based on the improvement
When I got the problem, the first thought was, how did it come out? , in the middle of the time has not yet begun to think about the right to go straight to the internet to see a ready-made, but finally still do not allow themselves to do so
After 1.1-point thinking, ideas are becoming more and more achievable within their capabilities.
A few days ago saw a sentence, began to panic, "algorithm is the soul of the program", because they understand the algorithm too little
Now that you know, just try.
An approach to the problem of-N queen by algorithm-backtracking