一、什么是递归?
程序调用自身的编程技巧称为递归(recursion)。
递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或?间接调用自身的一种方法它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。
递归的主要思考方式在于:把大事化小。
我先拿一道题来将递归“大事化小”呈现出来:
题目:输入一个四位数,并将这个数的个位、十位、百位、千位按顺序打印出来。
下面我不用递归的方法将这道题写出来如下:
#include<stdio.h>
int print(int num)
{
int i,k;
int j = 3;
int a[4];
for (i = 0; i < 4; i++)
{
a[i] = num % 10;
num = num / 10;
}
i = 0;
while (i <= j)
{
k = a[i];
a[i] = a[j];
a[j] = k;
i++;
j--;
}
for (i = 0; i < 4; i++)
printf("%d ", a[i]);
return 0;
}
int main()
{
int num = 0;
scanf_s("%d", &num);
int ret = print(num);
return 0;
}
调试结果如下:
那么用递归的方法应该怎么写呢?递归的大事化小又是怎样体现的呢?
代码如下:
#include<stdio.h>
int print(int num)
{
if (num > 9)
{
print(num / 10);
}
printf("%d ", num % 10);
return 0;
}
int main()
{
int num;
scanf_s("%d", &num);
int ret = print(num);
return 0;
}
二、递归是怎样进行的呢?
由于num=1234讲起来太复杂,我在这里用num=12讲解更通俗易懂。
因为刚开始num=12>9,所以if语句会进行,if语句中调用print函数,由红线所示,再次进入函数,此时形参的数为num/10=1<9 跳出if语句打印结果。打印完结果后又会回到上一未完成的print函数,上一print函数已经进行完if语句,所以会继续打印结果num%10=2.最终打印结果为 1 2.
总结:递归:递推+回归
三、使用递归需要什么条件呢?
由上可知,在定义函数时使用递归,使代码量减少了很多,并且只用了少量的程序就可描述出解题过程所需要的多次重复计算。
递归策略虽然提高了我们写代码的效率,但是难道递归策略什么时候都可以用吗?
如果我们将定义函数中的if语句去掉 那这就成为了一个死递归 得不到我们想要的结果。
再如果我们把print(num/10)变为print(num,那最终都无法接近num<9这个条件,最终一直会处于递推过程,最终也不会达到我们想到的结果。
所以使用递归策略是有前提的,也就是他的条件:
>存在限制条件,当满足这个限制条件时,递归便不再继续。
>:每次递归调用之后越来越接近这个限制条件
四、练习
下面再来一道题,同样也是利用递推策略来做。
题目:编写函数不允许创建临时变量,求字符串长度。
#include <string.h>
#include<stdio.h>
int my_strlen(char* str);
int main()
{
char arr[] = "abc";
int len = my_strlen(arr);
printf("%d\n", len);
return 0;
}
int my_strlen(char* str)
{
int count = 0;
while (*str != '\0')
{
count++;
str++;
}
return count;
}
上面解法虽对,但是是不符合题意的,我们引用了一个临时变量count。
那么正确解法应该如何做呢?
#include <string.h>
#include<stdio.h>
int my_strlen(char* str)
{
if (*str == '\0')
return 0;
else
return 1 + my_strlen(str+1);
}
int main()
{
char arr[] = "abc";
int len = my_strlen(arr);
printf("%zd\n", len);
return 0;
}
这个解法运用的就是递归,在定义函数中,if(*str=='\0')便是他的限制条件,从数组首元素地址开始读取时,每读取一位就会return 1 + my_strlen(str+1); my_strlen(str+1)中的str+1便是进行下一元素的读取。这样便可算出字符串长度,并且没有引用临时变量。