引子
老师正在做一个班级学生(4人)年龄调查的一项工作:
老师在问甲:你多少岁?
甲回答道:我比乙2岁!
老师又问乙:你多少岁?
乙回答道:我比丙2岁!
老师又问丙:你多少岁?
丙回答道:我比丙2岁!
老师又问丁:你多少岁?
丁回答道:我10岁!
老师在表上做了以下操作:
╔═══╦═══╗ =======》 ╔═══╦═══╦═══╗
║ .甲. ║乙+2║ =======》 ║ .甲. ║乙+2║ .16. ║
╠═══╬═══╣ =======》 ╠═══╬═══╬═══╣
║ .乙. ║丙+2║ =======》 ║ .乙. ║丙+2║ .14. ║
╠═══╬═══╣ =======》 ╠═══╬═══╬═══╣
║ .丙. ║丁+2║ =======》 ║ .丙. ║丁+2║ .12. ║
╠═══╬═══╬═══╗ ==》 ╠═══╬═══╬═══╣
║ .丁. ║ .—. ║ .10. ║ ==》 ║ .丁. ║ .—. ║ .10. ║
╚═══╩═══╩═══╝ ==》 ╚═══╩═══╩═══╝
于是,老师就知道了所有学生的年龄了。
分析:
| 老师开始并不知道任何一位同学的年龄,
问 甲 后得知其比乙大两岁,
问 乙 后得知其比丙大两岁,
问 丙 后得知其比丁大两岁,
问 丁 后得知其10岁,
| 由原来已知0人年龄,通过一番询问后慢慢得知了所有人的年龄。
| 年龄慢慢浮现出来了:
知道丁的年龄后,得知丙的年龄。
知道丙的年龄后,得知乙的年龄。
知道乙的年龄后,得知甲的年龄。
知道甲的年龄后,得知所有人的年龄。
这就是
递归算法的操作特点
- 每一步执行动作都一样;
- 每调用一次规模缩小;
- 结果通过一步步层层退出。
递归算法的定义
定义
当函数的定义中,其内部操作又直接或间接地出现对自身的调用,则称这样的程序嵌套定义为递归定义。 |
---|
直接调用:
函数自身调用自身
| 从前有座山,山里有座庙,庙里有位老和尚在给小和尚讲故事,故事是:
从前有座山,山里有座庙,庙里有位老和尚在给小和尚讲故事,故事是:
从前有座山,山里有座庙,庙里有位老和尚在给小和尚讲故事,故事是:
从前有座山,山里有座庙,庙里有位老和尚在给小和尚讲故事,故事是:
……
间接调用:
函数间相互调用
|从前有座山,山里有座庙,庙里有位老和尚在给小和尚讲故事,故事是:
未来有座城,城里有栋楼,楼里有个程序猿在 Ctrl(唱跳rape篮球) 写递归函数,运行结果为:
从前有座山,山里有座庙,庙里有位老和尚在给小和尚讲故事,故事是:
未来有座城,城里有栋楼,楼里有个程序猿在写递归函数,运行结果为:
从前有座山,山里有座庙,庙里有位老和尚在给小和尚讲故事,故事是:
未来有座城,城里有栋楼,楼里有个程序猿在写递归函数,运行结果为:
……
递归算法的基本框架
| 递归算法是有个最基本的框架滴!
#include <iostream>//导入C++标准库。
using namespace std;//使用标准的命名空间“std”。
int recursion(/*递归参数*/)
{
if(/*终止条件*/)return 0;//←“return 0”停止函数,返回0。
return recursion(/*传参*/);//←调用自身,传递参数。
}
还比如说上面那个引子如果用递归算法解决的话,就是这样写:
#include <iostream>//导入C++标准库。
using namespace std;//使用标准的命名空间“std”。
int fx(int n)//第n个人
{
if(age==10/*终止条件*/)return 10;//←“return 10”停止函数,返回最后已知丁的年龄为10岁。
return fx(n-1/*往后问一个人*/)+2;//←调用自身,传递参数,运算年龄,每个人都比后面那个人要大两岁。
}
int main(void)//主函数。
{
int n;//声明n来存输入的量。
cin>>n;//将输入量存入n中。
cout<<fx(n);//调用函数“fx”,将n作为参数传入“fx”函数中并输出函数“fx”的返回值。
return 0;//返回0,停止运行主函数。
}
递归算法应用
计算数的阶乘函数
#include <iostream>//导入C++标准库。
using namespace std;//使用标准的命名空间“std”。
int fx(int n)//第n个数
{
if(n==1/*终止条件*/)return 1;//←“return 1”停止函数,返回最后乘到1后就不需要再乘下去了。
return n*fx(n-1/*往后乘一个数*/);//←调用自身,传递参数,运算阶乘积,每个数都比后面那个数要大1。
}
int main(void)//主函数。
{
int n;//声明n来存输入的量。
cin>>n;//将输入量存入n中。
cout<<fx(n);//调用函数“fx”,将n作为参数传入“fx”函数中并输出函数“fx”的返回值。
return 0;//返回0,停止运行主函数。
}
计算数的非负整数次幂
#include <iostream>
using namespace std;
int fx(int x,int n)
{
if(n==0)return 1;
return fx(x,n-1)*x;
}
int main(void)
{
int n,m;
cin>>n>>m;
cout<<fx(n,m);
return 0;
}
最大公约数
#include <iostream>
using namespace std;
int fx(int a,int b,int i=min(a,b))//当参数有初始化时,可以不用传参,但不是不可以。
{
if(i==a || i==b)return 1;
else if(a%i==0 || b%i==0)return i;
return fx(a,b,i-1);
}
int main(void)
{
int a,b;
cin>>a>>b;
cout<<fx(a,b);
return 0;
}
最小公倍数
#include <iostream>
using namespace std;
int fx(int a,int b,int i=min(a,b))
{
if(i==a || i==b)return 1;
else if(a%i==0 || b%i==0)return i;
return fx(a,b,i-1);
}
int main(void)
{
int a,b;
cin>>a>>b;
cout<<a*b/fx(a,b);
return 0;
}
斐波那契数列
#include <iostream>
using namespace std;
int fx(int n)
{
if(n<=2)return 1;
return fx(n-1)+fx(n-2);
}
int main(void)
{
int n;
cin>>n;
cout<<fx(n);
return 0;
}
作者为初中生,有问题见谅,欢迎指出,不介意私聊,请多关照!
了解更多有关→“C++算法设计的专栏”←
了解更多有关→“C++的专栏”←