前言
C语言允许函数调用它自己,这种调用过程称为递归。递归有时难以捉摸,有时却很方便实用。
可以使用循环的地方通常都可以使用递归。有时用循环解决的问题比较好,但有时用递归解决问题会更好。递归方案简洁,但效率却没有循环高。
演示递归
阶乘
n! = n * (n-1) * (n-2) * ...* 1(n>0)
下面还是以阶乘为例子,循环写法为:
int factorial(int n)
{
int product = 0;
while(n>0){
product *= n;
n--;
}
return product;
}
用递归实现阶乘:
int factorial(int n)
{
if(n == 1)//需要一个条件,告诉它何时停止。
return 1;
else
return n * factorial(n - 1);
}
这里要说一下,某个数的阶乘等于起始数乘以比它小一的数的阶乘。例如,factorial(5) 与 5 * factorial(4) 相同。
问题:
既然用递归和循环来计算都可以问题,那么到底应该使用哪一个呢?一般而言,选择循环比较好,首先,每次递归都会创建一组变量,所以递归使用的内存更多,而且每次递归调用都会把创建的一组新变量放在栈中。递归调用的数量受限于内存空间。其次,由于每次函数调用要花费一定的时间,所以递归的执行速度较慢。
递归和倒序计算
下面我们通过一个示例,来演示递归倒序的用法。
#include <stdio.h>
//递归演示
void print_number(int n);
void print_string(const char *str);
int main(int argc, char const *argv[])
{
print_number(1);
//print_string("abcd");
return 0;
}
//
void print_number(int n)
{
printf("Up %d: n address %p\n",n,&n);
if (n < 5)
print_number(n+1);
printf("Drop %d: n address %p\n",n,&n);
}
//倒序打印字符串
void print_string(const char *str)
{
if (!*str)
return ;
print_string(str + 1);
putchar(*str);
printf("\n");
}
输出结果:
在使用递归函数时,递归函数必须包含能让递归调用停止的语句。通常,递归函数都使用if或者其他等价的测试条件在函数形参等于某特定值时终止递归。
递归的优缺点
递归既有优点也有缺点。优点是递归为某些编程问题提供了最简单的解决方案。缺点是一些递归算法会快速消耗计算机的内存资源。还有一点就是递归不方便阅读与维护。
递归解决爬楼梯的问题
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/*爬楼梯的问题,解决重复计算,采用数据保存方法*/
int helper(int n ,int *vlaue);
int helper(int n ,int *vlaue);
int main(int argc, char const *argv[])
{
printf("\r\nvalue%d ,%d",2,climb_staris(2));
printf("\r\nvalue%d ,%d",3,climb_staris(3));
printf("\r\nvalue%d ,%d",4,climb_staris(4));
printf("\r\nvalue%d ,%d",5,climb_staris(5));
printf("\n");
return 0;
}
int helper(int n ,int *vlaue)
{
if(vlaue[n] != 0)
{
return vlaue[n];
}
vlaue[n] = helper(n - 1,vlaue) + helper(n - 2,vlaue);//使用双递归
return vlaue[n];
}
int climb_staris(int n)
{
int *vlaue = NULL;
int res = 0;
vlaue = (int *)malloc(sizeof(int)*(n+1));
if(vlaue == NULL)
{
return -1;
}
memset(vlaue,0,sizeof(int)*(n + 1));
vlaue[0] = 0;
vlaue[1] = 1;
vlaue[2] = 2;
vlaue[3] = 3;
res = helper(n,vlaue);
free(vlaue);
return res;
}
输出结果: