Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Презентации 2часть / Лекция_18_Рекурсия .ppt
Скачиваний:
27
Добавлен:
11.05.2015
Размер:
388.1 Кб
Скачать

Рекурсивный вызов может быть прямым,

икосвенным

Procedure B(j:byte);Forward;

Procedure A(i:byte);

begin

...

B(i);

end;

Procedure B;

begin

...

A(j);

end;

используется опережающее описание с помощью стандартной директивы Forward

02.07.19

41

Организация выхода из рекурсии

Function F(i:integer):<тип>;

Var …

Begin

If i=i0 then F:=ao

else begin

 

. . .

 

F:=F(i 1);

 

. . .

 

end;

End;

 

 

02.07.19

42

Условия окончания рекурсии

Подобно любым циклическим алгоритмам рекурсивные подпрограммы могут приводить к своеобразному зацикливанию, когда в процессе последовательного перехода к нижнему уровню не выполняется условие, обеспечивающее нахождение тривиальной подзадачи.

Обычно окончание реализуют след. образом:

Рекурсивный параметр n при каждом обращении уменьшают

n-1 или увеличивают n+1

проверяют условие достижения тривиальной задачи

if (n=Nmin) или if(n=Nmax).

Важно также сделать оценку максимальной глубины рекурсии чтобы убедиться, что она достаточно мала и не приводит к переполнению программного стека

02.07.19

43

О целесообразности использования рекурсивных подпрограмм

Как мы видели, рекурсивные алгоритмы особенно подходят для задач, допускающих рекурсивное разбиение на элементарные подзадачи.

Однако это не означает, что для решения таких задач бесспорно употребление рекурсивных подпрограмм.

Более того, опыт рекурсивного программирования алгоритмов на неподходящих для этого примерах вызвал широко распространенное предубеждение, что их использование абсолютно неэффективно.

02.07.19

44

Неподходящий пример

-вычисление чисел Фибоначчи

• а) b0=0; b1=1;

б) bn=bn-1+bn-2

Изящная рекурсивная подпрограмма:

Function Fb(n:word):word;

begin

if n=0 then Fb:=0

else if n=1 then Fb:=1

else Fb:=Fb(n-1)+Fb(n-2)

end;

02.07.19

Элементарные

45

подзадачи

Работа подпрограммы для F=Fb(5) Дерево из 2n-1 обращений

 

 

 

b5=5

 

 

 

b3=2

 

 

 

 

b4=3

 

 

 

 

 

 

 

 

 

 

 

 

 

b2=1

 

 

b3=2

 

 

 

b =1

 

 

 

 

 

 

2

 

 

b1=1

 

 

 

 

 

b2=1

b =0

b1=1

b0=0

b1=1

b1=1

 

0

 

 

 

 

 

 

 

 

 

 

 

b0=0

b1=1

Из этого представления видно, что не выполняется основное

требование стратегии «разделяй и властвуй» – разбиение производится на зависимые подзадачи, решение которых при

рекурсивной реализации многократно повторяются

02.07.19

46

Решение с помощью итерационного алгоритма по стратегии динамического программирования

Function Fb(n:word):word;

Var i,x,y,z:word;

begin if n=0 then Result:=0

else if n=1 then Result:=1 else

begin

x:=0; y:=1

for i:=2 to n do

begin

z:=x+y;

x:=y;

y:=z;

end end;

Result:=y;

end;

Промежуточные решения запоминаются в x,y,z и нет

 

повторов

47

02.07.19

рекомендация

Из этого примера следует, что не нужно применять рекурсию там, где есть очевидное итерационное (табличное) решение.

В принципе, любую рекурсивную подпрограмму можно преобразовать в чисто итеративную (табличную). Однако во многих случаях это требует явной организации стека и преобразования настолько затуманивают суть программы, что ее бывает трудно понять.

Решение следующей задачи является примером разумного применения рекурсии.

02.07.19

48

Задача о Ханойской башне

Имеются три стержня s1,s2,s3.

На первом из них нанизаны n дисков различных диаметров, образующих правильную пирамиду чем выше расположен диск, тем меньше его диаметр.

Требуется переместить всю башню на второй стержень, причем диски можно переносить по одному, нельзя помещать диск на диск меньшего диаметра, для промежуточного хранения можно использовать третий диск

02.07.19

49

Ханойская башня

02.07.19

50