递归学习

今天学长教了递归,下面说说我对递归的一些理解。

 

以下面这个题目为例:

题目描述

Ø例5.2 求Fibonacci数列问题。
─斐波那契数列指的是这样一个数列:
─0、1、1、2、3、5、8、13、21、……
─F[0]=0, F[1]=1, F[i]=F[i-1]+F[i-2], i>=2;
编程输出前n个Fibonacci数

输入

输入n

输出

输出前n个Fibonacci数

样例输入

5

样例输出

0
1
1
2
3


当求F[5]时,它们的层数关系如下:

求F[5]时就要知道F[4]和F[3]的值,而F[4]的值等于F[3]+F[2],F[3]的值等于F[2]+F[1],依次递归下去,由于F[1]和F[0]的值知道,所以直到等于F[1]或F[0]时递归结束。

 

具体代码如下:

 

 1 #include <iostream>
 2 using namespace std;
 3  
 4 int f(int x){
 5     if(x == 0){
 6         return 0;
 7     }
 8     else if(x == 1){
 9       return 1;
10     }
11     else return f(x-1)+f(x-2);
12 }
13 int main(){
14     int n;
15     cin >> n;
16     for(int i = 0; i < n; i++){
17         cout << f(i) << endl;
18     }
19     return 0;
20 }

 

类似的递归问题还有:

题目描述

对1~ n 的 n个整数进行全排列(n<=9),编写程序输出所有可能的排列组合. 用递归算法实现.

输入

输入n

输出

输入n个整数的所有可能的排列组合.

样例输入

3

样例输出

   1   2   3
   1   3   2
   2   1   3
   2   3   1
   3   2   1
   3   1   2

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 using namespace std;
 5 void f(int arr[], int k, int m){
 6     if(k == m){
 7         for(int i = 0; i <= m; i++){
 8             printf("%4d",arr[i]);
 9         }
10         printf("\n");
11     }
12     else{
13         for(int i = k; i <= m; i++){
14             swap(arr[i], arr[k]);
15             f(arr, k+1, m);
16             swap(arr[i], arr[k]);
17         }
18     }
19 }
20 int main(){
21     int n;
22     cin >> n;
23     int a[11];
24     for(int i = 0; i < n; i++)
25         a[i] = i+1;
26     f(a,0,n-1);
27     return 0;
28 }

 

 

题目描述

汉诺(Hanoi)塔问题:古代有一个梵塔,塔内有三个座A、B、C,A座上有n个盘子,盘子大小不等,大的在下,小的在上(如图)。有一个和尚想把这n个盘子从A座移到C座,但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下,小盘在上。在移动过程中可以利用B座,要求打印移动的步骤。如果只有一个盘子,则不需要利用B座,直接将盘子从A移动到C。

输入

输入盘子个数n

输出

输出盘子最少移动的步骤

样例输入

3

样例输出

1:A->C
2:A->B
3:C->B
4:A->C
5:B->A
6:B->C
7:A->C


 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 void move(char x, char y);
 5 void f(int n, char a, char b, char c){
 6     if(n == 1)
 7         move(a, c);
 8     else{
 9         f(n-1,a,c,b);
10         move(a,c);
11         f(n-1,b,a,c);
12     }
13 }
14 void move(char x, char y){
15     static int i = 1;
16     printf("%d:%c->%c\n",i++,x,y);
17 }
18 int main(){
19     int n;
20     cin >> n;
21     f(n, 'A', 'B','C');
22     return 0;
23 }

 

题目描述

八皇后问题
是一个古老而著名的问题,是回溯算法的典型案例。
该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出的,在8*8格的国际象棋上摆放八个皇后;使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上;
问有多少种摆法, 输出所有可能的解?

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 using namespace std;
 5 const int N = 8;
 6 int a[N][N] = {0};
 7 void Print(){
 8     static int ans = 1;
 9     printf("Case %d:\n",ans++);
10     for(int i = 0; i < N; i++){
11         for(int j = 0; j < N; j++){
12             printf("%c ",a[i][j]?'Q':'.');
13         }
14         printf("\n");
15     }
16     printf("\n");
17 }
18 bool Safety(int row, int col){
19     for(int i = 0; i < row; i++){
20         for(int j = 0; j < N; j++){
21             if(a[i][j]&&(j==col||abs(row-i)==abs(col-j)))
22                 return false;
23         }
24     }
25     return true;
26 }
27 void BlackTrack(int i){
28     if(i >= N){
29         Print();
30         return;
31     }
32     else{
33         for(int j = 0; j < N; j++){
34             a[i][j] = 1;
35             if(Safety(i,j)){
36                 BlackTrack(i+1);
37             }
38             a[i][j] = 0;
39         }
40     }
41 }
42 int main(){
43     BlackTrack(0);
44     return 0;
45 }

 

 

输入

没有输入

输出

输出所有可能的解

 
 

posted @ 2017-03-18 20:18  starry_sky  阅读(948)  评论(0编辑  收藏  举报