数据结构之递归
定义:一个函数直接或间接调用自己
递归需要满足的三个条件:
1.递归必须有一个明确的中止条件
2.该函数所处理的数据规模必须在递减
3.这个转化必须是可解的
循环和递归:
递归:
易于理解
速度慢,存储空间大
循环:
不易理解
速度快,存储空间小
举例:
1.求阶乘
这一个所知道的信息就是 n! = n * (n-1)!;
这个时候,我们可以让程序不停的调用这个方法以便达到这种所谓的结果。
1 #include <stdio.h> 2 long sum(long n); 3 long sum(long n){ 4 long kk = 1; 5 if(n ==1){ 6 return kk; 7 }else{ 8 kk = n * sum(n-1); 9 return kk; 10 } 11 } 12 int main(void){ 13 printf("fff %l\n",sum(32)); 14 return 0; 15 16 }
//在程序中需要注意的是:C语言里面没有比较明确的规定long和int的字节数,所以如果大于字节范围就会出现变成零的可能性.
2.1+2+3+..+100 的和
PS:这里就不再贴代码与上面概念一致
函数的调用:
当在一个函数的运行期间调用另一个函数时,在运行被调函数之前,系统需要完成三件事:
1).将所有的实际参数,返回地址等信息传递给被调函数保存。
2).为被调函数的局部变量(也包括形参)分配存储空间
3).将控制转移到被调函数的入口
从被调函数返回主调函数之前,系统也要完成三件事:
1).保存被调函数的报错结果
2).释放被调函数所占的存储空间
3).依照被调函数保存的返回地址将控制转义到调用函数。
3.汉诺塔
汉诺塔最主要的就是三个步骤:
1)将n-1个盘子从A经C移到B
2)将n从A直接移到C
3)将n-1个盘子从B经A移到C
1 #include <stdio.h> 2 3 void hannuota(int n,char A,char B,char C){ 4 5 if(1 == n){ 6 printf("将编号为%d的盘子从%c移到%c\n",n,A,C); 7 }else{ 8 9 hannuota(n-1,A,C,B); 10 printf("将编号为%d的盘子从%c移到%c\n",n,A,C); 11 hannuota(n-1,B,A,C); 12 } 13 return; 14 } 15 16 17 int main(void){ 18 19 int n; 20 char ch1 = 'A'; 21 char ch2 = 'B'; 22 char ch3 = 'C'; 23 printf("请输入A柱子上面原始有的盘子个数!"); 24 scanf("%d",&n); 25 printf("\n"); 26 hannuota(n,ch1,ch2,ch3); 27 28 return 0; 29 }
4.走迷宫
递归的应用
1.树和森林就是以递归的方式定义的
2.数和图的很多算法就是递归实现的
3.很多数学公式就是以递归的方式定义的
例如:斐波拉基序列:1 1 2 3 5 ...