對於棧有些問題還不是很熟悉,所以暫時需要些時間去理解,需要多寫些代碼去體會,,棧還有一個重要應用是在程序設計語言中實現遞歸,所以這次主要是講遞歸的實現,大家熟悉的階乘函數,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 }
編譯結果如下圖:
當不斷按Enter的時候,會陸續出現Solution一直到Solutioin92,再按Enter會退出了。如下圖
小結:
遞歸是一種將問題分而治之的思想,解決問題的時候首先就要建立遞歸的模型;
如上圖到Solution92的時候就結束了,所以解決遞歸問題首先要有邊界條件,否則將死循環;