学习不易,需要坚持。
递归
程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。(来自百度百科)
巧用下幅图帮助理解:
1.递归和非递归分别实现求第n个斐波那契数。
2.编写一个函数实现n^k,使用递归实现
3. 写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和,
例如,调用DigitSum(1729),则应该返回1+7+2+9,它的和是19
4.递归和非递归分别实现strlen
5.递归和非递归分别实现求n的阶乘
6.
编写一个函数 reverse_string(char * string)(递归与非递归实现)
实现:将参数字符串中的字符反向排列。
要求:不能使用C函数库中的字符串操作函数。
1.
//递归和非递归分别实现求第n个斐波那契数并打印前40项
#include <stdio.h>
int fab1(int n)
{
//非递归
int a = 1 ;
int b = 1 ;
int c = 0 ;
if(n <= 2)
{
return 1 ;
}
else
{
int i = 1 ;
for(i = 3; i<=n; i++)
{
c = a + b ;
a = b ;
b = c ;
}
}
return c ;
}
int fab2( int n)
{
//递归
if(n <= 2)
{
return 1 ;
}
else
{
return fab2(n - 1) + fab2(n - 2) ;
}
}
void Fab()
{
int i = 0 ;
int arr[40] = { 1, 1, 0 } ;
for(i=2; i<40; i++)
{
arr[i] = arr[i-1] + arr[i-2] ;
}
for(i=0; i<40; i++)
{
printf("%10d ", arr[i]) ;
if(0 == (i + 1) % 5)
printf("\n") ;
}
printf("\n") ;
}
int main()
{
int m = 0 ;
int order = 0 ;
int ret1 = 0 ; //用来接收非递归求得的值
int ret2 = 0 ;// 用来接收递归求得的值
printf("----------此程序用来计算斐波那契数列----------\n") ;
printf("\n请输入你想要计算第几个数列的值: ") ;
scanf("%d", &order) ;
ret1 = fab1(order) ;
ret2 = fab2(order) ;
printf("非递归求得第%d个斐波那契数列值为: %d\n", order, ret1) ;
printf("递归求得第%d个斐波那契数列值为: %d\n", order, ret2) ;
printf("\n----------将打印出前项斐波那契数列值----------\n") ;
Fab() ;
return 0 ;
}
运行结果:
//编写一个函数实现n^k,使用递归和非递归实现
#include <stdio.h>
int func1(int n, int k)
{
//非递归
int i = 1 ;
int ret = 1 ;
while(i <= k)
{
ret = ret * n ;
i++ ;
}
return ret ;
}
int func2(int n, int k)
{
//递归
if(0 == k)
{
return 1 ;
}
else if(1 == k)
{
return n ;
}
else
{
return n * func2(n, k-1) ;
}
}
int main()
{
int n = 0 ;
int k = 0 ;
int ret1 = 0 ;
int ret2 = 0 ;
printf("----------此程序用来计算n的k次幂----------\n") ;
printf("\n请给n和k赋值: ") ;
scanf("%d%d", &n, &k) ;
ret1 = func1(n, k) ;
ret2 = func2(n, k) ;
printf("\n非递归求得%d^%d = %d\n", n, k, ret1) ;
printf("递归求得%d^%d = %d\n", n, k, ret2) ;
printf("\n") ;
return 0 ;
}
运行结果:
// 写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和,
//例如,调用DigitSum(1729),则应该返回+7+2+9,它的和是
#include <stdio.h>
int DigitSum(int n)
{
int m = 0 ;
int sum = 0 ;
if(n != 0)
{
m = n % 10 ;
n = n / 10 ;
sum= m + DigitSum(n) ;
}
return sum ;
}
int main()
{
int n = 0 ;
int ret = 0 ;
printf("请输入一个非负整数: ") ;
scanf("%d", &n) ;
ret = DigitSum(n) ;
printf("各位和为%d\n", ret) ;
return 0 ;
}
//用递归和非递归模拟实现strlen()函数
#include <stdio.h>
int My_strlen1(char* p)
{
//非递归
int count = 0 ;
while(*p != '\0')
{
p++ ;
count++ ;
}
return count ;
}
int My_strlen2(char* str)
{
//递归
if(*str != '\0')
return 1+My_strlen2(str + 1) ;
else
return 0 ;
}
int main()
{
int lenth1 = 0 ;
int lenth2 = 0 ;
char str[] = "Happy" ;
lenth1 = My_strlen1(str) ;
lenth2 = My_strlen2(str) ;
printf("----------此程序用来模拟实现strlen()函数----------\n") ;
printf(" 非递归求得\"Happy\" 长度为: %d\n", lenth1) ;
printf(" 递归求得\"Happy\" 长度为: %d\n", lenth2) ;
return 0 ;
}
运行结果:
//递归和非递归分别实现求n的阶乘
#include <stdio.h>
int fun1(int n)
{
//非递归
int mul = 1 ; //保存乘积
while(n > 0)
{
mul = mul * n ;
n-- ;
}
return mul ;
}
int fun2(int n)
{
//递归
if(n <= 1)
{
return 1 ;
}
else
{
return n * fun2(n - 1) ;
}
}
int main()
{
int n = 0 ;
int ret1 = 0 ;
int ret2 = 0 ;
printf("----------此程序来计算n的阶乘----------\n") ;
printf("请输入n的值: ") ;
scanf("%d", &n) ;
ret1 = fun1(n) ;
ret2 = fun2(n) ;
printf("非递归求得%d! = %d\n",n, ret1) ;
printf("递归求得%d! = %d\n",n, ret2) ;
return 0 ;
}
运行结果:
6.
//编写一个函数 reverse_string(char * string)(递归与非递归实现)
//实现:将参数字符串中的字符反向排列。
//要求:不能使用C函数库中的字符串操作函数。
#include <stdio.h>
#include <string.h>
int My_strlen(char* str)
{
int lenth = 0 ;
if(*str == '\0')
{
return 0 ;
}
while(*str != '\0')
{
str++ ;
lenth++ ;
}
return lenth ;
}
void Reverse_string1(char* str)
{
//非递归
int left = 0 ;
int right = My_strlen(str) - 1 ;
while(left <= right)
{
char temp = str[left] ;
str[left] = str[right] ;
str[right] = temp ;
left++ ;
right-- ;
}
}
void Reverse_string2(char* str)
{
//递归
char* p = str ;
if(*p == '\0')
{
return ;
}
else
{
Reverse_string2(p+1) ;
printf("%c", *p) ;
}
}
int main()
{
char str[] = "gfedcba" ;
printf("----------此程序将字符串逆转----------\n") ;
printf("逆转前字符串为: %s\n", str) ;
printf("递归逆转后字符串为: ") ;
Reverse_string2(str) ;
printf("\n") ;
Reverse_string1(str) ;
printf("非递归逆转后字符串为: %s\n", str) ;
printf("\n") ;
return 0 ;
}