主要思想
把阶数较高的某一个过程,转化为阶数较低相同类型的过程,称为递归算法。采用递归编写程序能使程序变得非常简单而清晰。递归的主要思想包括三个方面:
a) 定义形式是递归定义的。
b) 数据之间的关系(即数据结构)按递归定义。
c) 问题本身没有明显的递归结构,但用递归求解比用迭代求解更简单。
? 例题分析
阶乘函数定义(n!)描述如下:
fac(n)= 1 (当n=0时);
n×fac(n-1)(当n>0时),请编程实现从键盘输入n值,通过调用函数求f(n)的值.
[参考程序]
program digui1;
var n:integer;
function fac(n:integer):real;
begin
if n=0
then fac:=1
else fac:=n*fac(n-1) ;
end;
begin
write(‘n=’);readln(n);
writeln(‘fac(‘,n,’)=’,fac(n):6:2);
end.
小结
采用递归算法来编程,程序结构清晰简洁,它能使一个蕴涵递归关系且结构复杂的程序简洁精练,增加可读性。但递归过程的实现决定了递归算法的效率往往很低,费时和费内存空间。在实际编程中,如果能使用递推法解决的,应考虑用递推法,其效率更高些。用递推法求解阶乘函数的思路是:先求fac(1),再求fac(2),…,直到求出fac(n),参考程序如下:
program digui2;
var n:integer;
function fac(n:integer):realll;
var I:integer;
m:real;
begin
m:=1;
for I:=1 to n do m:=m*I;
fac:=m;
end;
begin
write(‘n=’);readln(n);
writeln(‘fac(’,n,’)=’,fac(n):6:2);
end.
说实话 如果真的想理解好递归
我建议把八皇后问题看透彻。
八皇后就是非常经典的递归加回朔
program eightqueens;
var
x:array[1..8] of integer; {当前8个皇后所摆的方案}
a,b,c:array[-7..16] of boolean; {分别是列,对角线,反对角线}
i:integer;
procedure print; {打印本次方案}
var k:integer;
begin
for k:=1 to 8 do write(x[k]:4);
writeln;
end;
procedure try(i:integer); {使用回溯法递归求解,试遍所有的情况,是一种递归枚举}
var j:integer;
begin
for j:=1 to 8 do
if a[j] and b[i+j] and c[i-j] {若(i,j) 可放}
then begin
x[i]:=j; {则第i行就放在第j列}
a[j]:=false; {做上相应位置不能放的标志}
b[i+j]:=false;
c[i-j]:=false;
if i<8 then try(i+1){8个没放完,则继续放}
else print; {放完去打印方案}
a[j]:=true;{回溯回来后,撤去不能放的标志}
b[i+j]:=true;
c[i-j]:=true
end
end;
begin
for i:=-7 to 16 do{初始化为每个位置均可放}
begin
a[i]:=true;
b[i]:=true;
c[i]:=true
end;
try(1);{从第一行开始}
end.
现在循环从 i=1 ,j:=1 to 8 do 开始 此时 计算机检测到 i=1 j=1
(简化为(1,1))为空,占用该位置并令该位置对应的斜线和水平方向的位置为 false ,然后程序就开始去执行try(2),注意此时计算机在i=1
这层仅仅走了一个循环(j=1)就跳到了i=2 ,第2层里此时计算机从j:=1 to 8 do 又开始循环,排除 j=1,j=2 得到
(2,3)注意计算机第2层里也只是走了3(j=3)个循环然后又跳到了i=3 这层依次类推得到(3,5),(4,2)(5,4)而在i=6
这层里计算机从j:= 1 to 8 do 都没有找到合适的位置,此时注意在i=6 这层里计算机计算机将返回到i=5
这层里,(因为用了递归)并且释放(5,4)该位置,为什么要释放呢?因为原因很简单如果不释放的话
该位置对应的斜线和水平方向会对以后的几层造成影响,让计算机误认为false。此时的在i=5这层里 j=4没有循环结束,然后计算机又会从j=5到 8
开始去找合适的位置 ,如果找不到又会返回到上一层依次类推直到计算机找到一组解
输出,假设在(8,3)这个位置是计算机找到的一组解,此时计算机又会从j=4到8 开始循环,如果找不到
计算机就会返回上一层的即i=7这层接着上一次的跳出位置走完以后的循环,依次类推不断的返回,跳出,
求解,(即令前几个位置不变,从第8个位置变换,没有空位置的。接会返回上一层)最后返回到i=1这层里,注意此时在这层里也只是走了j=1个循环然后计算机就又开始从j=
2 去试着找....大家有没有算过求出所有的解要走过多少个循环?我想估计也不下1000个吧。其实整个过程就是一个重复的过程(即递归)倒着想在i=7
这层里的j=1 位置即(7,1) 计算机会去试从(8,1)到(8,8)这8 个位置,而在(7,2)也同样会去试这8 个位置
等等在(6,1)会试(7,1)到(7,8) 等。 这是正着考虑(1,1)这里计算机会试着从(2,1)到(2,8)这8个位置而在这8
个位置里并没有试完就有空位置
(2,3)此时计算机会在这个位置对下一层里开始试(3,1)..(3,8)依次类推,试不通的返回,接着走完上一层直到试完所有的位置!