小论c语言递归与递推
来源:互联网 发布:python网页架构 编辑:程序博客网 时间:2024/04/20 01:41
递归和递推都是算法设计中的难点,算法又十分相近,很多和我一样学生误认为是一回事,非常容易混淆。其实它们之间既有相似点,又有明显的区别。
递推一般用循环来解决,从已知条件到未知逐渐接近结果;
(1)将复杂运算分解为若干重复的简单运算
(2)后一步骤建立在前一步骤之上
(3)计算每一步骤的方法相同
(4)从开始向后计算出结果
(5)使用循环结构,通过多次循环逐渐逼近结果
递归一般自己调用自己,从未知到已知,把规模大的、较难解决的问题变成规模较小的、易解决的同一问题。规模较小的问题又变成规模更小的问题,并且小到一定程度可以直接得出它的解,从而得到原来问题的解。
(1)每一次递归都缩小问题规模,直到问题足够小
(2)使用选择分支语句
(3)从后往开始逐步逼近
(4)达到最开始,再把初始值带入往后逐一求解
下面通过例子逐个介绍。
递推:
一。 解阶乘 n! = 1*2*3*4*....*(n-1)*n.
fun(int n) { long s=1; int i; for(i=1;i<=n;i++) s=s*i; return s; }
二。捕鱼问题
A,B,C,D,E五个渔夫夜间合伙捕鱼,,第二天清A先醒来,他把鱼均分五份,把多余的一条扔回湖中,便拿了自己的一份回家了,B醒来后,也把鱼均分五份,把多余的一条扔回湖中,便拿了自己的一份回家了,C,D,E也按同样方法分鱼。问5人至少捕到多少条鱼?
这也是一个递推问题,递推关系式为 F(n+1) = F(n)*5/4+1 (i = 1,2,3,4) F(5)即捕鱼的总数
#include <stdio.h>int main(){ int i, n, f[5], flag; flag = 1; n = 1; while (flag == 1) { f[0] = 5*n+1; flag = 0; for (i=1; i<5; i++) { if (f[i-1]%4!=0) { flag=1; break; } f[i] = 5*f[i-1]/4+1; } n++; } printf("%d\n",f[4]); return 0;}
三。平面分割
#include <stdio.h>int main(){ int i, n, f2, f1; while (1) { scanf("%d",&n); if (n==0) { break; } f1 = 2; for (i=1; i<=n; i++) { f2 = f1+2*(i-1); f1 = f2; } printf("%d\n",f2); } return 0;}
递归:
一。计算组合数
问题:计算组合数C(10,3)(组合数:从n个不同元素中,任取m(m≤n)个元素并成一组,叫做从n个不同元素中取出m个元素的一个组合;从n个不同元素中取出m(m≤n)个元素的所有组合的个数,叫做从n个不同元素中取出m个元素的组合数。)
我们可以利用组合恒等式:
#include <stdio.h>int Cmn(int m, int n ){ if (m<0 || m<n || n<0) { return 0; } if (m==n) { return 1; } if (n==1) { return m; } return Cmn(m-1,n)+Cmn(m-1,n-1);}int main(){ printf("C(10,3) = %d \n",Cmn(10,3)); return 0;}
二。 解阶乘 n! = 1*2*3*4*....*(n-1)*n.
long ff(int n){ long f; if(n<0) printf("n<0,input error"); else if(n==0||n==1) f=1; else f=ff(n-1)*n; return(f);}main(){ int n; long y; printf("\ninput a inteager number:\n"); scanf("%d",&n); y=ff(n); printf("%d!=%ld",n,y);}
三。Hanoi 汉诺塔问题
本题算法分析如下,设A上有3个盘子:
1将A上的2个圆盘移到B
2将A上的1个圆盘直接移到C
3将B上的2个圆盘移到C其中第2步可以直接实现
将第1步分解:(借助C)
1.1
1.2
1.3
将第3步分解:(借助A)
3.1
3.2
3.3
由此可知,将3个圆盘从A移到C,需要7步,将n个圆盘从A移到C需要2的n次方减1步,要进行第n步,需要先进行第n-1步,可分为3个步骤
1将A上n-1个圆盘借助C移到B
2将A上剩下的1个圆盘直接移到C
3将B上n-1个圆盘借助A移到C
#include <stdio.h>void Move(int n,char a,char b){ printf("%d:%c-->%c\n",n,a,b);}void Hanoi(int n,char a,char b,char c){ if(n==1)//将A上的1个圆盘直接移到C,递归退出条件 Move(n,a,c); else { Hanoi(n-1,a,c,b);//将A上n-1个圆盘借助C移到B Move(n,a,c);//将A上剩下的1个圆盘直接移到C Hanoi(n-1,b,a,c);//将B上n-1个圆盘借助A移到C }}int main(){ int n; printf("\ninput number:"); scanf("%d",&n); Hanoi(n,'A','B','C'); return 0;}/* 打印结果 input number:3 1:A-->C 2:A-->B 1:C-->B 3:A-->C 1:B-->A 2:B-->C 1:A-->C*/
下面通过一个具体例子比较一下递归和递推。
long f(int n){ if(n<=2) return 1; else return f(n-1)+f(n-2);}
递推解:
long f(int n){ long t;f1=1,f2=1; if(n<=2) reutrn 1; for(int i=3;i<=n;i++) { t=f1+f2; f1=f2; f2=t; } }
由此可见,递归重在“归”,你要求的是什么,就直接求什么,至于要怎么去调用、怎么去求,让函数自己一步一步去反复调用;递推重在“推”,是按照我们平时做数学的方法来算。编程时递归比较特殊,表现在函数自身调用自身,这样编程代码紧凑,程序的可读性好,但效率低,还可能导致堆栈溢出,特别是递归层次比较多时。一般来说,递归程序都可以用循环程序实现,用循环程序实现虽然较难理解,但安全可靠。
- 小论c语言递归与递推
- 2、小论c语言递归与递推
- 递归递推 C
- 递推与递归
- 递推与递归
- 递推与递归
- 递推与递归
- 递归与递推
- 递推与递归
- 递推与递归
- (C语言)整数划分问题 递归和递推
- 递推递归练习 C
- 递推递归练习C
- 递推递归练习C
- 递推递归练习 C
- 《递归递推练习》C
- 递归递推练习 C
- 递归递推c-递归的函数
- JS判断手机浏览器
- 将DataSet中的内容输出到Excel文件
- 判断点在多边形内部的方法(Java版)
- 大话设计模式之UML
- java虚拟机 换时区
- 小论c语言递归与递推
- java验证码识别--1
- 物联网培训预示着我们将进入智能时代
- 黑马程序员-String、StringBuffer和StringBuilder
- c#文件读写操作
- 开发者需知的10类工具
- OS
- 使用spring @Scheduled注解执行定时任务
- Android中的多线程和异步处理