Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекция 6 Итерация и рекурсия.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
348.16 Кб
Скачать

{Функция на Pascal}

Function Factorial(N:integer): longint;

Begin

If N<=1

Then Factorial:=1

Else Factorial:=Factorial(N-1)*N

End;

{Процедура на Pascal}

Procedure Factorial(N:integer; Var F:longint);

Begin

If N<=1

Then F:=1

Else Begin Factorial(N-1, F); F:=F*N End

End;

Пример вызова из основной программы:

x:= Fact(a); writeln( a, ‘!= ', x); Factorial(a, F); writeln( a, ' != ', F);

Результат 5!= 120 5!= 120

Пример: Числа Фибоначчи

Известным примером рекуррентной последовательности второго порядка является последовательность чисел Фибоначчи, для которой , а для : . Применительно к рекуррентным последовательностям часто ставится задача найти -й элемент последовательности.

Для решения этой задачи достаточно хранить в памяти элемент последовательности. Решение задачи разбивается на два основных этапа: начальную установку и продвижение по последовательности. Для вычисления чисел Фибоначчи первый этап выглядит следующим образом: a:=1; b:=1 Продвижение по последовательности на один элемент вперед выполняется так: for k:=3 до n do begin c:=a+b; a:=b; b:=c; end; Каждый из элементов последовательности, начиная с третьего в данном случае, как бы отбирает значение у следующего элемента. Последний элемент, после того как у него отобрали значение, получает новое путем применения рекуррентной формулы. Безвозвратно теряемые старые значения уже не нужны, поскольку на последующие вычисления они повлиять не могут. Составим алгоритм нахождения n-го числа Фибоначчи с начала до конца: program fibonacciITER;

var

n, f, a, b, c, k: integer;

begin

writeln (‘Введите число n');

readln ( n );

a:=1; b:=1;

for k:=3 to n do

begin

c:=a+b;

a:=b;

b:=c

end;

f:=c;

writeln (n, '-й член последовательности Фибоначчи равен ', f); end.

В следующей программе числа Фибоначчи вычисляются вначале с использованием итерации, а затем с использованием рекурсии, причем глубина рекурсии отображается. Перед каждым рекурсивным вызовом команда delay(900) приостанавливает вывод глубины рекурсии на 0.9 с.

program fibonacci;

uses crt;

var n,result:integer;

function fibit(n:integer):integer;

var a,b,c,i:integer;

begin

a := 1; b := 1;

if (n=1) or (n=2)

then fibit :=1

else begin

for i:= 3 to n do

begin c :=a+b; a := b; b :=c; write (c,' '); end;

fibit :=c;

writeln;

end;

end;

function fibrek(n:integer):integer;

begin

if (n=1) or (n=2) then fibrek := 1

else

begin

writeln ('Глубина рекурсии:',n);

delay(900) ;

fibrek := fibrek(n-1)+fibrek(n-2);

end;

end;

begin

clrscr;

write('Какое по счету число Фиббоначчи вывести? ');

readln(n);

writeln('Итеративно:',fibit(n):5);

writeln('Рекурсивно:');

result := fibrek(n);

writeln;

write(result);

end.

Этот пример демонстрирует прежде всего различия между итерацией и рекурсией. Итерации необходим цикл и вспомогательные величины; итерация сравнительно ненаглядна (см. fibit в приведенном выше примере).

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

if (n=1) or (n=2) then fibrek := 1

else fibrek := fibrek(n-1)+fibrek(n-2);

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

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

Рекурсивный метод решения задач является чуть ли не базовым методом решения алгоритмических задач. Рекурсия, дополненная идеями динамического программирования, жадными алгоритмами и идеей отсечения, превращается в тяжёлую артиллерию программистов. Но не следует забывать, что краткость записи рекурсивных функций не всегда означает высокую скорость их вычисления. И есть ряд задач, в которых рекурсия просто вредна (такова, например, задача вычисления кратчайшего пути в графе).