棧與遞歸的實現


 

 

  對於棧有些問題還不是很熟悉,所以暫時需要些時間去理解,需要多寫些代碼去體會,,棧還有一個重要應用是在程序設計語言中實現遞歸,所以這次主要是講遞歸的實現,大家熟悉的階乘函數,2階Fibonacci數列和Ackerman函數等,其次還有的數據結構,如二叉樹、廣義表等,由於結構本身固有的遞歸特性,則它們的操作可遞歸的描述,另外還有一類問題,雖然問題本身沒有明顯的遞歸結構,但是遞歸求解比迭代求解更簡單,如八皇后問題、Hanoi塔問題等。

  遞歸是一種數學上分而治之的思想,它將大型復雜問題轉化為與原問題相同但規模較小的問題進行處理,數學表示如下:

      

 

  下面我以一個八皇后問題來說一下這兒的遞歸問題,在一個8X8國際象棋中,有8個皇后,每個皇后占一格,要求皇后間不會出現相互“攻擊”的現象,即不能有兩個皇后處在同一行,同一列或者同一對角線上。那么怎么來實現這個想法呢?下面是我的算法思路:先給兩個了、變量i,j賦值為1,從第i行開始,恢復j的當前值,判斷第j個位置。1、位置j可放入皇后,標記位置(i,j),i++,j = 1; 2、位置j不可放入皇后,j++,i = 1;  3、當j>8時候,j--,繼續上述循環; 4、第八行有位置可以放入皇后。

  實現代碼如下:

 1 #include <stdio.h>
 2 #define N 8
 3 
 4 typedef struct _tag_Pos  5 {  6     int ios;  7     int jos;  8 } Pos;  9 
10 static char board[N+2][N+2]; 11 static Pos pos[] = { {-1, -1}, {-1, 0}, {-1, 1} }; 12 static int count = 0; 13 
14 void init() 15 { 16     int i = 0; 17     int j = 0; 18     for(i=0; i<N+2; i++) 19  { 20         board[0][i] = '#'; 21         board[N+1][i] = '#'; 22         board[i][0] = '#'; 23         board[i][N+1] = '#'; 24  } 25     for(i=1; i<=N; i++) 26  { 27         for(j=1; j<=N; j++) 28  { 29             board[i][j] = ' '; 30  } 31  } 32 } 33 
34 void display() 35 { 36     int i = 0; 37     int j = 1; 38     for(i=0; i<N+2; i++) 39  { 40         for(j=0; j<N+2; j++) 41  { 42             printf("%c", board[i][j]); 43  } 44         printf("\n"); 45  } 46 } 47 
48 int check(int i, int j) 49 { 50     int ret = 1; 51     int p = 0; 52     for(p=0; p<3; p++) 53  { 54         int ni = i; 55         int nj = j; 56         while( ret && (board[ni][nj] != '#') ) 57  { 58             ni = ni + pos[p].ios; 59             nj = nj + pos[p].jos; 60             ret = ret && (board[ni][nj] != '*'); 61  } 62  } 63     
64     return ret; 65 } 66 
67 void find(int i) 68 { 69     int j = 0; 70     if( i > N ) 71  { 72         count++; 73         printf("Solution: %d\n", count); 74  display(); 75  getchar(); 76  } 77     else
78  { 79         for(j=1; j<=N; j++) 80  { 81             if( check(i, j) ) 82  { 83                 board[i][j] = '*'; 84                 find(i+1); 85                 board[i][j] = ' '; 86  } 87  } 88  } 89 } 90 
91 int main() 92 { 93  init(); 94     find(1); 95     
96     return 0; 97 }
queen

 

  編譯結果如下圖:

當不斷按Enter的時候,會陸續出現Solution一直到Solutioin92,再按Enter會退出了。如下圖

 

小結:

  遞歸是一種將問題分而治之的思想,解決問題的時候首先就要建立遞歸的模型;

  如上圖到Solution92的時候就結束了,所以解決遞歸問題首先要有邊界條件,否則將死循環;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM