在数学中,关于递归函数的定义是这样的:对于某一函数f(x),其定义域是集合A,那么若对于A集合中的某一个值x1,其函数值f(x1)由f(f(x1))决定,那么就称f(x)为递归函数。
在编程语言中,程序调用自身的编程技巧称为递归。递归作为一种算法在程序设计语言中广泛应用。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,大大减少了程序的代码量。
递归的主要思考方式在于:把大事化小
递归的两个必要条件:
- 存在限制条件,当满足这个限制条件的时候,递归便不再继续
- 每次递归调用之后越来越接近这个限制条件
不多说,直接上代码:
例1:递归和非递归分别实现求第n个斐波那契数(斐波那契数列指的是这样一个数列 1, 1, 2, 3, 5, 8, 13, 21…这个数列从第3项开始,每一项都等于前两项之和。)
首先用递归的方法:
int fib(int i)
{
if(i<=2)
return 1;
else
return fib(i-1)+fib(i-2); //递归调用fib()
}
int main()
{
int i = 0;
int ret = 0;
printf("请输入:");
scanf("%d",&i);
ret = fib(i);
printf("第%d个斐波那契数是:%d\n",i,ret);
system("pause");
return 0;
}
在使用fib这个函数计算第40个斐波那契数时特别的费力,那我们再试试非递归写一次:
int fib(int n)
{
int a = 1;
int b = 1;
int c = 1;
int i = 0;
for(i=0; i<n-2; i++)
{
c = a+b;
a = b;
b = c;
}
return c;
}
这次再计算较大的数时,可以比较容易求出来
其实,许多问题是以递归的形式进行解释的,这只是因为它比非递归的形式更为清晰。但这些问题的迭代实现往往比递归实现效率高,当一个问题相当复杂,难以用迭代实现时,此时递归实现的简洁性便可以补偿它所带来的运行时开销。
再来看几个递归的例子:
例2:写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和,例如,调用DigitSum(1729),则应该返回的和是19
int DigitSum(int n)
{
if(n>9)
return DigitSum(n/10)+n%10;
else
return n;
}
int main()
{
int n = 0;
int ret = 0;
scanf("%d", &n);
ret = DigitSum(n);
printf("组成它的数字之和为:%d\n", ret);
system("pause");
return 0;
}
例3:编写一个函数实现n^k,使用递归实现
int Pow(int n, int k)
{
if(k==0)
return 1;
else if(k>=1)
{
return n*Pow(n, k-1);
}
}
int main()
{
int n = 0;
int k = 0;
int ret = 0;
scanf("%d%d", &n, &k);
ret = Pow(n, k);
printf("%d\n", ret);
system("pause");
return 0;
}
例4:编写一个函数实现将参数字符串中的字符反向排列
void reverse_string(char* arr)
{
char *left = arr;
char *right = arr+strlen(arr)-1;
while(left<right)
{
char tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
int main()
{
char arr[] = "mercylin";
reverse_string(arr);
printf("%s\n", arr);
system("pause");
return 0;
}
好啦,关于函数递归就简单介绍到这。