汉诺塔:
题目描述:一块板上有三根针 A、B、C。A 针上套有 64 个大小不等的圆盘,按照大的在下、小的在上的顺序排列,要把这 64 个圆盘从 A 针移动到 C 针上,每次只能移动一个圆盘,移动过程可以借助 B 针。但在任何时候,任何针上的圆盘都必须保持大盘在下,小盘在上。从键盘输入需移动的圆盘个数,给出移动的过程
一个盘
我们先简化为一个盘,假设这个盘在A针,直接移动到C针 我们暂把这个过程定为move(A,C)。
两个盘
当两个盘时
(注意:每次移动的都是针最上面的那个盘 所以不用指定盘的编号)
1)
A移到B,
A移到C,move(A,C)----------------------分界-------------------
B移到C。
三个盘
然而到三个盘时我们就只有一种解法了
A到C,
A到B,
C到B,
A到C,move(A,C)----------------------分界-------------------
B到A,
B到C,
A到C。
分界线上方我们可以看作从A针经由C针到B针
分界线下方我们可以看作从B针经由A针到C针
四个盘
A—B
A—C
B—C
A—B
C—A
C—B
A—B
A—Cmove(A,C)----------------------分界-------------------
B—C
B—A
C—A
B—C
A—B
A—C
B—C
分界线上方我们可以看作从A针经由C针到B针
分界线下方我们可以看作从B针经由A针到C针
与三盘时情况相同
总结
从三盘开始整个移动盘的过程可总结为三个大过程
hanoi(n-1,A,C,B)//从A针经由C针到B针
move(A,C)//
hanoi(n-1,B,A,C)//从B针经由A针到C针
如图所示:
如果想详细了解每个递归调用在堆栈中的详细过程请移步 B站,对初学者较为复杂。
对函数中每一个递归调用都看成只是一个简单操作,只要接口一致,必能实现规格说明中定义功能,切忌想的太深太远
代码如下:
#include <stdio.h>
void hanoi(int, char, char, char);
void move(char, char);
int main()
{
int n;
printf("Input the number of diskes:");
scanf("%d", &n);
printf("\n");
hanoi(n, 'A', 'B', 'C');
return 0;
}
void hanoi(int n, char A, char B, char C)
{
if (n == 1)//当n等于1的时候直接从A移到C
move(A, C);
else
{
hanoi(n - 1, A, C, B);
move(A, C);
hanoi(n - 1, B, A, C);
}
}
void move(char getone, char putone)
{
printf("%c -> %c\n",getone, putone);
}
----------------------------------
青蛙跳台阶:
题目描述1:一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
规律
分别列出当n=1,2,3,4,5,6,7…时青蛙跳台阶的方法个数
当n=1时:1种跳法
当n=2时:2种跳法(1,1)(2)
当n=3时:3种跳法(1,1,1)(2,1)(1,2)
当n=4时:5种跳法(1,1,1,1)(1,1,2)(2,2)(2,1,1)(1,2,1)
… … …
观察到:1+2=3;2+3=5… …
此为斐波那契数(唯一区别是a,b的初始值不一样)
此下为代码:
#include <stdio.h>
int Fab(int n)
{
if (n < 3)
{
return n;
}
else {
return Fab(n - 1) + Fab(n - 2);//相当于c=a+b
}
}
int main()
{
int n;
scanf_s("%d", &n);
printf("%d", Fab(n));
}
---------------------------------------------------------------------
题目描述2:一只青蛙一次可以跳上1级台阶,也可以跳上2级…也可以跳上n阶。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
规律
设跳上一个n阶台阶需要的方法数为jump(n)
当为n-1阶台阶且第一次跳一阶:jump(n-1)种跳法
当为n-2阶台阶且第一次跳一阶:jump(n-2)种跳法
当为n-3阶台阶且第一次跳一阶:jump(n-3)种跳法
当为n-4阶台阶且第一次跳一阶:jump(n-4)种跳法
… … …
当为1阶台阶且第一次跳一阶:jump(1)种跳法
即跳上n阶台阶的方法总数为jump(n):
=jump(n-1)+jump(n-2)+jump(n-3)+jump(n-4)+…+jump(1)
为此我们可以将其看作数学问题
先总结成一类通解易知为 jump(n - 1) * 2;
构造递归函数
#include <stdio.h>
int jump(int n)
{
if(n<3)
{
return n;
}
else
{
return jump(n - 1) * 2;//数学通式
}
}
int main()
{
int n=0;
scanf("%d",&n);
printf("%d",jump(n));
}
总结
1):大事化小
2):对函数中每一个递归调用都看成只是一个简单操作,只要接口一致,必能实现规格说明中定义功能,切忌想的太深太远
3):递归函数不要调用的太深否则会导致栈溢出