递归
定义:
一个函数直接或间接调用自己
递归满足的三个条件
1.必须有一个明确的终止条件
2.该函数所处理的数据规模(值可以增,规模要减)必须递减
3.程序必须是可解的
4.递归是必须有返回值的
循环和递归
所有的循环理论上讲都可以转换为递归
没有明确执行行数的都用递归
递归:
易于理解
速度慢
存储空间大
循环:
不易理解
速度快
存储空间小
举例:
1.求阶乘
2.1+2+3....+100
3.斐波那契数列
4.汉诺塔
5.走迷宫
递归的应用:
树和森林就是以递归的方式定义的
树和图很多算法都是通过递归来实现的
很多数学公式就是以递归的方式定义的
递归的基本操作
//1.求阶乘
/*************************
递归.求阶乘
*************************/
# include <stdio.h>
long f (int n)
{
long val;
if (1==n)
return 1;
if (n > 1)
{
return val = f(n-1)*n;
}
}
int main ()
{
int n, val=1;
scanf ("%d", &n);
printf ("%d的阶乘是%ld\n", n, f (n));
for (int i=1; i<=n;i++)
{
val = val*i;
}
printf ("%d的阶乘是%ld", n, val);
return 0;
}
// 2.1+2+3….+10
/*************************
递归.1+2+3....+100
*************************/
# include <stdio.h>
int f (int n)
{
if (1==n)
return 1;
else
{
return n+=f(n-1);
}
}
int main ()
{
int n,val = 0;
scanf ("%d", &n);
if (n==0)
{
printf ("从0加到%d是%ld", n, val);
return 0;
}
for (int i=1;i<=n;i++)
val=val+i;
printf ("从0加到%d是%ld\n", n, val);
printf ("从0加到%d是%ld", n, f (n));
return 0;
}
// 3.斐波那契数列
/*************************
递归.斐波那契数列
*************************/
//前面两项之和构成了后一项的数列被称为斐波那契数列
//递归是一定有返回值的//递归是不一定有返回值的。。。比如说那个汉诺塔。。。真的不知道返回个什么值
//当数比较大的时候,可以很明显的看出来,循环是真的比递归快,特别是我用的这台近10年前买的机子,我把这句段话打完了它才从40跑到42.。。。唉
# include <stdio.h>
# include <malloc.h>
int f (int n)
{
if (n<=2)
return n == 0?0:1;//三元运算符 当n=0的时候返回0,否则返回1
else
return f (n-1) + f (n-2);
}
int main ()
{
int n;
scanf ("%d", &n);
int * a =(int*)malloc(sizeof(int)*n);//动态分配数组是int * a不是int a[]
a[0]=1;
a[1]=1;
//for循环实现
for (int i=2;i<n; i++)
{
a[i] = a[i-1]+a[i-2];
}
for (i=0;i<n;i++)
{
printf ("第%d个数是%d\n", i+1, a[i]);
}
printf ("\n");
//递归实现 //这里应该是i=1开始的,i=0传过去判断,返回0那个数列是从1开始的。。但是原理上011358也符合定义
for (i=1;i<=n;i++)
{
printf ("第%d个数是%d\n", i, f (i));
}
/*斐波那契数列的数学小魔术
int k;
for (i=1;i<=n;i++)
{
k = f(i);
if(k==3524578)
break;
}
printf ("第%d个数是%d\n", i, f (i));
*/
return 0;
}