嵌套调用
在一个函数的函数体中,调用另一函数。
例题
输入两个整数,求平方和
//3_7.cpp
#include <iostream>
using namespace std;
int fun2(int m) {
return m * m;
}
int fun1(int x,int y) {
return fun2(x) + fun2(y);
}
int main() {
int a, b;
cout << "Please enter two integers(a and b): ";
cin >> a >> b;
cout << "The sum of square of a and b: " << fun1(a, b) << endl;
return 0;
}
递归调用
函数直接或间接地调用自身。
实质:将原问题分解为新的问题,而解决新问题时候又用到原有问题的解法。按照这一原则分解下去,每次出现的新问题都是原有问题的简化的子集,而最终分解出来的问题,是一个已知解的问题。
递归过程
- 第一阶段:递推。将原有问题不断分解为新的子问题,逐渐从未知向已知推进,最终达到已知的条件,即递归结束的条件。这是由未知到已知的过程。
4!=4x3!➡3!=3X2!➡ 2!=2X1!➡1!=1x0!➡0! =1
- 第二阶段:回归。从已知的条件出发,按递归的逆过程,逐一求值回归,最终达到递推的开始处,结束回归过程阶段,完成递归调用。这是从已知到未知的过程。
4!=4x3!=24⬅3! =3x2!=6⬅2! =2x1!=2⬅1 !=1x0!=1⬅0!=1
递归条件
- 必须有递归终止的条件
- 函数有与递归终止条件相关的参数
- 在递归过程中,决定终止条件的参数有规律地递增或递减。
递归标准模式
有可对函数入口进行测试的基本情况
if(条件) //此处条件为基本情况
return(不需要递归的简单答案);
else
return(递归调用同一函数);
递归调用经典例题
求n!
公式
#include <iostream>
using namespace std;
//计算n的阶乘
unsigned fac(unsigned n) {
unsigned f;
if (n == 0)
f = 1;
else
f = fac(n - 1) * n;
return f;
}
int main() {
unsigned n;
cout << "Enter a positive integer: ";
cin >> n;
unsigned y = fac(n);
cout << n << "! = " << y << endl;
return 0;
}
例 用递归法计算从n个人中选k个人组成一个委员会的不同组合。
分析:由组合公式可得nCk=n-1Ck+n-1Ck-1
n=k或n=0时组合数为1
#include <iostream>
using namespace std;
//计算n的阶乘
unsigned comm(int n,int k) {
unsigned f;
if (k == 0 || n == k)
f = 1;
else
f = comm(n - 1, k) + comm(n - 1, k - 1);
return f;
}
int main() {
int x, y,z;
cout << "" << endl;
cin >> x >> y;
z = comm(x, y);
cout << z;
return 0;
}
例 汉诺塔
有三根针 A、B、C。A 针上有N 个盘子,大的在下,小的在上,要求把这N 个盘子从A 针移到C 针,在移动过程中可以借助B 针,每次只允许移动一个盘,且在移动过程中在三根针上都保持大盘在下,小盘在上。
分析:
将A上的n-1个盘子借助C移动到B
将A上的第n个盘子放在C上
将B上的n-1个盘子借助A放到C上
//3_8.cpp
#include <iostream>
using namespace std;
int move(char qidian, char zhongdian)
{
cout << qidian << "到" << zhongdian << endl;
return 0;
}
int hannuo(int n,char src,char med,char dest) {
if (n==1)
move(src,dest);
else
{
hannuo(n - 1, src, dest, med);
move(src, dest);
hannuo(n-1, med, src, dest);
}
return 0;
}
int main() {
int x=0, y=0,z=0;
cin >> x;
y = hannuo(x, 'A', 'B', 'C');
return 0;
}