1.什么是递归
程序调用自身的编程技巧被称为递归,递归作为一种算法在程序设计语言中广泛应用,一个过程或函数在其定义或说明种有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转换为一个原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可把大事化小,自己本身调用自己就是递归.
2.递归的两个必要条件
存在限制条件当满足这个限制条件的时候,递归便不再继续,每次递归调用之后越来越接近这个限制条件
练习1.
接收一个空整型值(无符号),按照顺序打印每一位,例如:1234,输出1234
//void表示函数不需要返回值
void printf(unsigned int n)
{
if(n> 9)
{
print(n / 10);
}
printf("%d",n % 10); //1234
}
int main()
{
unsigned int num = 0;
scanf("%u",&num); //1234
//递归是函数自己调用自己
print(num) //可以打印参数部分数字的每一位
return 0;
}
栈溢出地现象,和内存区原理
栈溢出现象
栈区:局部变量,函数形参
堆区:动态内存分配的
malloc/free, calloc,fealloc,
静态区:
全局变量,静态变量
写递归代码的时候:
1.不能死递归,都有跳出条件,每次递归逼近跳出条件
2.递归的层次不能太深,递归层次太深的时候也会有栈溢出的问题
void test(int n)
{
if (n<10000)
{
test(n+1);
}
}
int main()
{
test(1);
return 0;
}
50.函数递归2
编写函数不允许创建临时变量,求字符串的长度
int my_strlen(char * str)
{
if(*str != '\0')
return 1 + my_strlen(str + 1);
else
return 0;
}
int main()
{
char arr[] = "bit";
//['b']['i']['t']['\0']
//模拟实现一个strlen函数
printf("%d\n",my_strlen(arr))
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;
}
有一些功能:可以使用迭代的方式来实现,也可以使用递归
例:
n!
1*2*3*n
循环是一种迭代
练习4:斐波那契数列:前两个数之和为第三个数的结果,求第n个斐波那契数列
//算法销量太低,重复大量的计算
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 Fid(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);
wprintf("%d\n",ret);
printf("count=%d\n",count);
return 0;
}