1. 程式人生 > >N皇后問題,,回溯與迭代

N皇后問題,,回溯與迭代

窮舉法的例子,每行只能有一個,每列也只能有一個,整個棋盤共n個,可以以行為單位遍歷。從第一行開始,對行的每一列都進行判定,如果當前位置可以,則將其座標進棧,然後判斷下一行(因為一行只能有一個,當前行已經放置了),仍從第一列開始。當判斷到最後一行時,若有位置滿足,則一條路徑已經找到,輸出。否則,若最後一行所有列都遍歷完後仍不滿足,需要改變上一行的位置,尋找上一行中後面的可滿足的,更新棋盤,重點理解回溯的過程,queen(row+1)是在判斷第row行有一個合適位置(row,k)之後呼叫的,是在找k的for()迴圈中的。如一共有4行4列,當進行到queen(4)時,函式結束遞迴,輸出一個結果,刪除棧頂元素(最後一行的位置)此時queen(4)執行完成,返回到呼叫她的地方,即判斷第三行的(3,k),然後執行k++,繼續尋找第三行後面的可行位置。整個第三行找完以後,返回到(2,k'),進行k'++.....如此回溯,便可找到所有路徑。

#include<stdio.h> #include<stdlib.h> #include<math.h> #define  STACK_INIT_SIZE 100 #define  STACK_INCREMENT 10 #define max 10 #define  overflow -1 #define error -1 typedef struct{   int row;   int col; }ElemType; int tag=1; typedef struct{    ElemType * base;    ElemType * top;     int      stacksize;    int      len; }SqStack;//棧用於存放路徑 //棧的基本操作 void InitStack(SqStack * S){//問題:define int Status  函式返回OK(1)  前面關於int會錯誤,,寫返回void 會有沒有影響?    (*S).base=(ElemType *)malloc( STACK_INIT_SIZE*sizeof(ElemType));    if(!(*S).base) exit(overflow);       (*S).top=(*S).base;    (*S).stacksize=STACK_INIT_SIZE;    (*S).len=0; } void Push(int row,int col,SqStack * S){    ElemType e;    e.row=row;  e.col=col;    if((*S).top-(*S).base>=(*S).stacksize){      (*S).base=(ElemType *)realloc((*S).base,((*S).stacksize+STACK_INCREMENT)*sizeof(ElemType));      if(!(*S).base)  exit(overflow);      (*S).top=(*S).base+(*S).stacksize;      (*S).stacksize+=STACK_INCREMENT;    }   *(*S).top++=e;   (*S).len++; } int Pop(SqStack *S){    ElemType e;    if((*S).len==0)      return error;    e = *(--(*S).top);    (*S).len--;    }

void print_result(SqStack S){     ElemType * p=S.base;     printf("%d: ",tag);     for(;p<S.top;p++){       printf("(%d,%d) ",(*p).row+1,(*p).col+1);     }     printf("\n");     tag++; } int can_place(int row,int col,SqStack S){     ElemType * s=S.base;     while(s<S.top){       if((*s).col==col)          return 0;       else if(abs(row-(*s).row)==abs(col-(*s).col))//開始寫成行減=1,是全部的上下對角線啊,不是緊鄰的           return 0;       s++;     }     return 1; }

void queen(int row,int n,SqStack *S){      int k;      if(row==n)         {           print_result(*S);           Pop(S);         }       else{         for(k=0;k<n;k++){             if(can_place(row,k,(*S))){                Push(row,k,S);                queen(row+1,n,S);             }          }//for          if(k==n)            Pop(S);  //這一行沒有,刪除棧頂元素       }//else }

int main(){ int n; SqStack S; InitStack(&S); scanf("%d",&n);

queen(0,n,&S); return 0; }