1、递推算法
递推算法是一种用若干步可重复的简运算(规律)来描述复杂问题的方法。函数
递推是序列计算机中的一种经常使用算法。它是按照必定的规律来计算序列中的每一个项,一般是经过计算机前面的一些项来得出序列中的指定项的值。其思想是把一个复杂的庞大的计算过程转化为简单过程的屡次重复,该算法利用了计算机速度快和不知疲倦的机器特色。spa
例1:植树节那天,有五位同窗参加了植树活动,他们完成植树的棵树都不相同。问第一位同窗植了多少棵时,他指着旁边的第二位同窗说比他多植了两棵;追问第二位同窗,他又说比第三位同窗多植了两棵;... 如此,都说比另外一位同窗多植两棵。最后问到第五位同窗时,他说本身植了10棵。到底第一位同窗植了多少棵树?设计
分析:设第一位同窗植树的棵树为a1,欲求a1,需从第五位同窗植树的棵数a5入手,根据“多两棵”这个规律,按照必定顺序逐步进行推算:
(1) a5=10;
(2) a4=a5+2=12;
(3) a3=a4+2=14;
(4) a2=a3+2=16;
(5) a1=a2+2=18;blog
var
i,a:byte;
begin
a:=10;
for i:=1 to 4 do a:=a+2;
writeln('The Num is',a);
end.递归
本程序的递推运算可用下图示表示:
初始值a:=10-----i=1,a=a+2(12)-----i=2,a=a+2(14)------i=3,a=a+2(16)-----i=4,a=a+2(18)----输出a值数学
例2:十本不一样的书放在书架上,现从新摆放,使每本书都不在原来放的位置,有几种摆法?it
分析:当n个元素放在n个编号位置,元素编号与位置编号各不对应的方法数用M(n)表示,那么M(n-1)就表示n-1个编号元素放在n-1个编号位置且各不对应的方法数,其它类推。io
第一步,把第n个元素放在除n之外的某一个位置,好比位置k,一共有n-1种方法
第二步,放编号为k的元素,这时有两种状况:
一、把它放到位置n,那么对于剩下的n-2个元素,就有M(n-2)种方法
二、不把它放到位置n,这时对于这n-1个元素有M(n-1)种方法function
综上获得:
M(n)=(n-1)*[M(n-2)+M(n-1)] (n>=3)
var
n,i:byte;
a,b,c:longint;
begin
readln(n);
case n of
1: writeln(0);
2: writeln(1);
else begin
a:=0;b:=1;
for i:=3 to n do begin
c:=(i-1)*(a+b);
a:=b;b:=c;
end;
writeln(c);
end;
end;
end.
递推算法以初始(起点)值为基础,用相同的运算规律,逐次重复运算,直至运算结束。这种从“起点”重复相同的方法直至到达必定“边界”,犹如单向运动,用循环能够实现。递推的本质是按规律逐次推出(计算)先一步的结果。
2、递归
若是函数体或过程体中出现调用其自身的语句,称为递归调用。这样的函数或过程称为递归函数或递归过程。
例3:设计一个计算n!的递归程序
根据数学含义,n!可由下面的公式表示:
n!=1 当n=0时
n!=n*(n-1)! 当n>0时
根据以上公式推理,为了求n!能够先求出(n-1)!,为了求(n-1)!又能够先求出(n-2)!……,如此递推,直到n=0。因为n=0时已定义为1,再由0!=1又一步步反向推回,求出1!、2!……最终获得n!
var
n:integer;
function fct(t:integer):integer;
begin
if t=0 then fct:=1
else fct:=t*fct(t-1);
end;
begin
readln(n);
writeln(n,'!=',fct(n));
end.
例4:汉诺(hanoi)塔问题。给定三根杆A、B、C和大小不一样的几个盘子,这些盘子按尺寸递减顺序套在A杆上,如图。咱们的任务是把这些盘子从A杆移到C杆且保持原来堆放顺序;在实现任务时,规定每次只能移动一个盘子,不容许大的盘子放在小的盘子上面,B杆能够做为辅助存放杆,求出每一步应该如何移动。
题目要求将n个盘子由A杆移到C杆可用一样的方法:
一、先(递归地)将A杆上面的n-1个盘子移到B杆(借助C杆)
二、而后把A杆上惟一的一个盘子移到C杆
三、再把B杆上的n-1个盘子(递归地)移到C杆(借助A杆)
var
n:integer;
procedure move(n:integer;a,b,c:char);
begin
if n=1 then writeln(a,'--->',c)
else begin
move(n-1,a,c,b);
writeln(a,'--->',c);
move(n-1,b,a,c);
end;
end;
begin
readln(n);
move(n,'A','B','C');
end.
递归结构的程序具备结构清晰,容易阅读和理解的优势,写出的程序较简短,但在处理递归问题中,须要保留每次递归调用时的参数和局部变量,这样就占用大量的存储空间和花费较多的机器时间,效率较低。
用递归过程或函数解决问题时应注意:
一、求解的问题是否符合递归的描述,要解决的问题是否能够化为与原问题相同的子问题
二、过程体或函数体中必须有递归结束的条件,这个条件就是递归边界
3、做业
一、zerojudge:a21六、a04二、b12七、a51九、d580、d2十二、d810
二、用递归方法求两个正整数的最大公约数
三、读入一个任意位数的正整数,按颠倒过来的顺序将其输出(利用递归过程)
四、从键盘输入任意长度的一串字符,其中包括数字和字母,并以星号“*”结束。利用递归的方法将这串字符中的数字字符按相反的次序个输出。例如:输入Delphi6TP70Ada586*,输出为685076。