本文章是关于递归和相关例题的个人心得,学习中。
目录
前言
递归是一种相当实用且极具数学上的美感和简洁性的一种方法,汉诺塔和青蛙跳台阶都属于是递归算法中的经典问题,许多新人在学习编程语言的过程中或多或少应该听过这类问题,本篇文章也是作者通过学习实践做出来的解题过程和总结。
一、什么是递归
程序调用自身的编程技巧称为递归(recursion)。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序语句就可以描述出解题过程中所需要的多次重复计算,大大地减少了程序的代码量。
二、递归的两个必要条件
1.存在限制条件,当满足这个限制条件的时候,递归便不再继续
2.每次递归调用之后越来越接近这个限制条件
× 错误示例:
int main(){
main(); //在主函数内再次调用主函数
return 0;
}
在主函数里再次调用主函数是可行的,但是该调用行为没有进行递归的界限约束,这会导致程序进入死循环,且最终会导致栈溢出。
√ 正确示例:
int fac(int n) {
int i = n;
if (n > 1) { //递归界限
i = i * fac(n - 1); //调用函数本身实现递归
}
else
return i;
}
int main() {
int n = 0;
int i = 0;
scanf("%d", &n);
i = fac(n);
printf("%d", i);
return 0;
}
如上图所示,该段代码就是一个简单的使用递归实现n的阶乘的例题
三、使用递归实现的经典例题(C实现)
1、汉诺塔问题
汉诺塔的条件非常简单:
通过一次移动一块圆盘的方式将塔1上的圆盘全部移动到塔3上
不管如何移动圆盘,每根塔上都不可以出现其中一个圆盘比下面的圆盘大的情况
圆盘数量较少的时候基本毫无压力,但是圆盘数量较大的时候,其完成方法就只能通过计算机来模拟过程和结果了。
那么我们如何通过编程来实现对任意数量圆盘的汉诺塔过程的模拟呢?
1 )问题分析
我们都知道,汉诺塔如果只有两个圆盘的时候,只需要将最上面的圆盘移动到(塔1、塔2、塔3在后文分别成为a、b、c)b上,然后将下面的圆盘移动到c上,再将第一步移动到b上的圆盘移动到c上就可以了,最主要的是初始塔(a)最下面的,最大的那个圆盘要在目标塔(c)的最下方,所以整个汉诺塔问题不论数量,都可以类似的分解成这个相似的过程构成。
hanoi(n)
↓
n号圆盘+hanoi(n-1)
↓
n号圆盘+(n-1)号圆盘+hanoi(n-2)
↓
...
↓
n号圆盘+...+hanoi(1)
2 )代码实现
通过这个思路,我们就可以以此来使用递归的方法实现解题。
void move(int n, char x, char y) {
printf("将圆盘%d从%c移动到%c\n", n, x, y);
}
void hanoi(int n, char a, char b, char c) {
if (n == 1) { //递归界限
move(n, a, c);
}
else {
hanoi(n - 1, a, c, b); //将第1到n-1号圆盘从a移动到b
move(n, a, c); //将第n号圆盘从a移动到c
hanoi(n - 1, b, a, c); //将b上的1到n-1号圆盘移动到c
}
}
int main() {
int n = 0;
printf("输入汉诺塔的初始圆盘数(int n > 0):");
scanf("%d", &n);
hanoi(n, 'a',' b', 'c');
return 0;
}
2、青蛙跳台阶问题
1 )问题描述
有一只青蛙,要跳到第n阶的台阶上,
青蛙一次可以选择跳一个台阶或者两个台阶,
问:该青蛙要跳到第n个台阶上,一共有多少种跳法?
2 )问题分析
青蛙一次可以跳1或者2个台阶,我们设一共有n个台阶,不管青蛙之前是怎么跳的,它最后要么跳了一个台阶达到第n阶,要么跳了两个台阶达到第n阶,所以要跳到第n个台阶上的所有跳法,就是跳到第(n-1)个台阶与跳到第(n-2)个台阶的跳法数量之和。n以内的每一个台阶都可以近似的划分成类似的过程,以此实现递归。
3 )代码实现
根据上述分析,该题同样可以使用递归的方法来实现解题。
int frog(int n) {
if (n == 1) { //递归界限
return 1;
}
else if (n == 2) {
return 2;
}
else
return frog(n - 1) + frog(n - 2); //递归的实现
}
int main() {
int count = 0;
int n = 0;
printf("输入一共有几个台阶:");
scanf("%d",&n);
count = frog(n);
printf("青蛙一共有%d种跳法",count);
return 0;
}
总结
以上就是作者关于递归的理解以及相关例题的实践过程笔记,写作不易,希望各位读者喜欢。