一个函数直接或间接地调用自己就是递归调用,递归调用是特殊的一种嵌套调用,递归即递推与回归,先有递推的过程,即把大事一步步化小,再有回归过程,递归需要有出口,即要有if的判断语句使递推结束,一步步接近出口,遇到出口再一步步回来, 大部分题目写出分段函数的形式是设计递归的关键。
注意:递归层次太深,容易出现栈溢出的现象,所以虽然递归代码简单,也不要太迷恋。
请看下面四道例题进一步理解递归思想。
1、求阶乘
首先找出递推的过程, 如 5!可以看做4!*5,进一步可以看做3!*4*5。
写下如图分段函数
//递归求阶乘
int Fact(int n) {
if (n == 0)
return 1; //递归出口
else
return n * Fact(n - 1);
}
对比循环求阶乘 递归的代码确实简单了不少。
//循环求阶乘
int main()
{
int n; cin >> n;
int ret = 1;
for (int i = 1; i <= n; i++) {
ret *= i;
}
cout << ret;
return 0;
}
2、 顺序打印一个整数的各位
容易实现的是一个整数的逆序打印,再通过一个数组存放起来逆序输出,但如何直接顺序打印呢,此处采用递归思想。打印123各位数,首先打印1的各位数,打印12的各位数,打印123的各位数,递推过程。
代码
顺序打印一个整数的各位
void Print(int n) { //123
if (n > 9) {
Print(n / 10);
}
cout << n % 10<<" ";
}
int main() {
int n;
cin >> n;
Print(n);
return 0;
}
运行结果
如果还有些不清楚整个过程,请看下图分析
3、求第n个斐波那契数
//递归求第n个斐波那契数
//1 1 2 3 5 8 13
int Fib(int n) {
if (n <= 2)
return 1;
else
return Fib(n - 1) + Fib(n - 2);
}
int main() {
int n=0; cin >> n;
cout<<Fib(n);
return 0;
}
对比循环
//循环求第n个斐波那契数
int main() {
int n; cin >> n;
int a = 1, b = 1, c = 1;
while (n >= 3) {
c = a + b;a = b;b = c;
n--;
}
cout << c;
}
4、求最大公约数
25与15 利用辗转相除法的思想找到递推过程依次求 25(a)与15(b) 15(b)与10 (a%b)
10与5 5与5 (递归出口)的最大公约数。
代码
int ploy(int,int);
int main() {
int a , b;
cin>> a >> b;
cout << ploy(a, b);
return 0;
}
int ploy(int a, int b)
{
if (a % b == 0)
return b;
else
return ploy(b, a % b);
}
运行结果