目录
什么是递归?
递归其实就是把一个复杂的问题转化成一个与原问题相似但规模较小的问题来求解,函数自己调用自己,递归最主要的思想就是大事化小。
递归的必要条件
递归必须存在条件,不然就会无限递归下去,造成死循环。
递归条件:
1.必循存在限制递归的条件,当达到这个条件递归不再进行。
2.每次递归之后会越来越接近这个条件。
什么时候用递归
1.当解决一个问题递归跟非递归都可以使用,那就可以用递归
2.当解决一个问题递归写起来很简单,非递归比较复杂,且递归没有明显问题,就用递归
3.如果说用递归解决问题,写起来简单,但是有明显问题,就不用递归
练习
1.接受一个整型值(无符号),按照顺序打印它的每一位。 例如: 输入:1234,输出 1 2 3 4.
利用递归思想,写一个打印函数,把1234每打印一次去掉最后一位然后加上。
print(1234);
print(123)+4;
print(12)+3+4;
print(1)+2+3+4
代码如下:
void print(unsigned int n)
{
if (n > 9)
{
print(n / 10);//123
}
printf("%d ", n % 10);
}
int main()
{
unsigned int num = 0;
scanf("%u", &num);
print(num);
return 0;
}
2.编写函数不允许创建临时变量,求字符串长度
递归思想:写一个函数my_strlen(),判断有没有遇到\0。
my_strlen("abcd");
1+my_strlen("bcd");
1+1+my_strlen("cd");
1+1+1+my_strlen("d");
1+1+1+1=4;
代码如下:
#include <string.h>
int my_strlen(char* s)
{
if(*s != '\0')
{
return 1 + my_strlen(s+1);
}
else
{
return 0;
}
}
int main()
{
char arr[10] = "abcdef";
//数组名arr是数组首元素的地址--char*
int len = my_strlen(arr);
printf("%d\n", len);
return 0;
}
3.求n的阶乘--递归方法
int Fac(int n)//递归方法
{
if (n <= 1)
{
return 1;
}
else
{
return n*Fac(n - 1);
}
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = Fac(n);
printf("%d\n", ret);
return 0;
}
4.求第n个斐波那契数
斐波那契数列 1 1 2 3 5 8 13 21...
前两个数字之和等于第三个
当n<=2时 返回1
当n>2时,返回Fib(n-1)+Fib(n-2)
int Fib(int n)//利用递归效率很低
{
if (n <= 2)
{
return 1;
}
else
{
return Fib(n - 1) + Fib(n - 2);
}
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = Fib(n);
printf("%d\n", ret);
return 0;
}
利用递归求,可能效率很低,会一直重复很多数据。
可以用循环的方法
int Fib(int n)
{
int a = 1;
int b = 1;
int c = 1;
while (n>2)
{
c = a + b;
a = b;
b = c;
n--;
}
return c;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = Fib(n);
printf("%d\n", ret);
return 0;
}
5.逆序字符串
提供俩种思路
#include <string.h>
void reverse_string(char* str)
{
int len = strlen(str);
//char* left = str;
//char* right = str + len - 1;
int left = 0;//'a'
int right = len - 1; //'f'
while (left<right)
{
char tmp = str[left];
str[left] = str[right];
str[right] = tmp;
left++;
right--;
}
}
方法二--递归
int my_strlen(char* str)
{
int count = 0;
while (*str != '\0')
{
count++;
str++;
}
return count;
}
void reverse_string(char str[])
{
int len = my_strlen(str);
char tmp = str[0];
str[0] = str[len - 1];
str[len - 1] = '\0';
if (my_strlen(str+1) >= 2)
{
reverse_string(str + 1);;
}
str[len - 1] = tmp;
}
int main()
{
char arr[] = "abcdef";
reverse_string(arr);
printf("%s\n", arr);//期望结果 fedcba
}
6.求1234的每一位之和
int Digitsum(int n)
{
if (n > 9)
{
return Digitsum(n / 10) + n % 10;
}
else
{
return n;
}
}
int main()
{
unsigned int num = 1234;
int ret = Digitsum(num);
printf("%d\n", ret);
return 0;
}
7.递归实现n的k次方
double Pow(int n, int k)
{
if (k < 0)
{
return n*(1.0/Pow(n, -k));
}
else if (k == 0)
{
return 1;
}
else
{
return n*Pow(n, k - 1);
}
}
int main()
{
int n = 2;
int k = 3;
double ret = Pow(n,k);
printf("%lf\n", ret);
return 0;
}