根据下面递归函数:调用函数Fun(2),返回值是多少( )
int Fun(int n)
{
if(n==5)
return 2;
else
return 2*Fun(n+1);
}
解析:
Fun(2)--->返回16
return 2*Fun(3) 2*8=16
|__Fun(3):8
return 2*Fun(4) 2*4=8
|__Fun(4):4
return 2*Fun(5) 2*2=4
|__Fun(5):2
return 2
因此,选择D
解析:
递归的两个条件:
1. 将问题转化为其子问题,子问题要与原问题具有相同的解法
2. 递归的出口
A:正确,限制条件即递归的出口,如果限制条件满足,递归程序就可以退出了
B:正确,因为每次递归,都是将原问题进一步缩小,缩小到限制条件时,就可以往回返,直到第一次递归调用
比如:递归求和
int Sum(int N)
{
if(N == 1)
return 1;
return Sum(N-1)+N;
}
假设:求Sum(4)的递归调用过程
Sum(4)<----
| |
| |
Sum(3)<----
| |
| |
Sum(2)<----
| |
| |
Sum(1)-----
C:错误,递归不能无限递归下去,否则会造成死循环和栈溢出
D:正确,因为每次递归,相当于都是一次新的函数调用,而每次函数调用系统必须给该函数划分栈帧空间,内部的递归函数没有退出,上层的递归就不能退出,栈帧就会累积许多块,如果累积超过栈的总大小,就会栈溢出。
/*
思路:
一个问题直接求解时不好求解,如果可以将其划分成其子问题,并且子问题和原问题有相同的解法时,就可以使用递归的方式解决
递归的两个条件:
1. 将问题划分成其子问题,要求:子问题要与原问题具有相同的解法
2. 递归的出口
1 N < 3
Fac(N)
Fac(N-1) + Fac(N-2) N >= 3
*/
long long Fac(int N)
{
if(N < 3)
return 1;
return Fac(N-1) + Fac(N-2);
}
/*
思路:
1 K==0
Pow(n,K) =
Pow(n, K-1)*n
*/
int Pow(int n, int k)
{
if(k==0)
return 1;
else if(k>=1)
{
return n*Pow(n, k-1);
}
}
/*
思路:
n n < 10
DigiSum(n) =
DibiSum(n/10)+n%10 // 前n-1位之和+第N位
*/
int DigitSum(int n)//1729
{
if(n>9)
return DigitSum(n/10)+n%10;
else
return n;
}
/*
Fac(N) = 1*2*3*……*N
递归方式实现:
1 N <= 1
Fac(N)
Fac(N-1)*N N >= 2
*/
long long Fac(int N)
{
if(N <= 1)
return 1;
return Fac(N-1)*N;
}
/*
循环方式:从1乘到N即可
*/
long long Fac(int N)
{
long long ret = 1;
for(int i = 2; i <= N; ++i)
{
ret *= i;
}
return ret;
}
/*
思路:
N N <= 9
Print(N)
Print(N-1), 打印N
*/
void print(unsigned int n)
{
if(n>9)
print(n/10);
printf("%d ", n%10);
}