在数学上,求n的阶乘,有两种表示方法
①n!=1×2×3×…×(n-2)×(n-1)×n
②n!=(n-1)!×n,0!=1!=1
这两种表示方法实际上对应到两种不同的算法思想
在第①种表示方法中,求n!要反复把1、2、3、…、(n-2)、(n-1)、n累乘起来,是循环的思想,要用循环结构来实现,代码如下:
long long n, F = 1;
cin >> n;
for(i=1;i<=n;i++) F = F*i;
在第②种表示方法中,求n!时需要用到(n-1)!。如果有一个函数f能实现求n的阶乘,其形式为:long long f(int n);,则该函数在求n!时要使用到表达式:n*f(n-1),f(n-1)表示调用f()函数去求(n-1)!
#include<iostream>
using namespace std;
long long f(int n)
{
if(n<0) return -1; //递归结束条件
else if(n==0 || n==1) return 1; //递归结束条件
else return n*f(n-1); //递归调用f函数
}
int main()
{
int N; cin >> N;
cout << f(N) << endl;
return 0;
}
f函数包含了一个if语句,前2个分支判断出特殊情况后,直接返回值,不再递归调用下去。这2个分支非常重要,这是递归结束条件。递归函数如果没有递归结束条件,会无限地递归调用下去,最终导致程序出错终止
在上述例子中,f()函数有一个特点,它在执行过程中又调用了f()函数,这种函数称为递归函数
具体来说,在执行一个函数过程中,又直接或间接地调用该函数本身,如下图所示,这种函数调用称为递归调用:包含递归调用的函数称为递归函数。实际编程时,递归函数主要是自己直接调用自己,间接调用非常少见
假设求3!,其完整执行过程如下图所示
在该例子中,求n转换成求(n-1)!,而(n-1)又可以转换成求(n-2)!,…,一直到1!=1。某些问题的求解可以转换成规模更小的、或者更趋向于求出解的同类子问题的求解,并且从这些子问题的解可以构造出原问题的解。这种求解问题的思想称为递归思想。递归思想需要用递归函数来实现