Сведение задачи к самой себе (рекурсия)


.

Рекурсивными называются процедуры и функции, которые вызывают сами себя. Рекурсия позволяет очень просто (без использования циклов) программировать вычисление функций, заданных рекуррентно, например факториала f(n)=n!:

f(0)=1 f(n)=n*f(n-1).

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

Факториал

Еще раз напомним рекурсивный алгоритм вычисления факториала:

program Factorial;

var N:word;

function F(n:word):longint;

begin

if n=0 then F:=1 else F:=n*F(n-1)

end;

begin

write('N=');readln(N);

writeln('N!=',F(N))

end.


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

Игра "Ханойская башня" состоит в следующем. Есть три стержня. Hа первый из них надета пирамидка из N колец (большие кольца снизу, меньшие сверху). Требуется переместить кольца на другой стержень. Разрешается перекладывать кольца со стержня на стержень, но класть большее кольцо поверх меньшего нельзя. Составить программу, указывающую требуемые действия.

Hапишем рекурсивную процедуру перемещения M верхних колец с A-го стержня на B-ый в предположении, что остальные кольца больше по размеру и лежат на стержнях без движения:

procedure Move(M,A,B:integer);

var C:integer;

begin

if M=1 then begin writeln ('сделать ход ',A,'->',B) end

else

begin

C:=6-A-B; {C - третий стержень: сумма номеров равна 6}

Move(M-1,A,C);

Move(1,A,B);

Move(M-1,C,B)

end

end;

Сначала переносится пирамидка из M-1 колец на третий стержень C. После этого M-ое кольцо освобождается, и его можно перенести на B. Остается перенести пирамиду из N-1 кольца с C на B. Чем это проще первоначальной задачи? Тем, что количество колец стало на единицу меньше. Теперь основную программу можно записать в несколько строк:

program Hanoi;

var N:integer;

procedure Move(M,A,B:integer);

.............

begin

write('N=');readln(N);

Move(N,1,2)

end.

Таким образом, ОСHОВHАЯ ИДЕЯ любого рекурсивного решения - свести задачу к точно такой же, но более простой (с меньшим значением параметра). Эта более простая задача имеет ту же формулировку, что и исходная, с той лишь разницей, что решаться она должна для более простых исходных данных. При этом какое-то минимальное значение параметра должно давать решение без рекурсивного вызова - иначе программа "зациклится" (последовательность рекурсивных вызовов будет бесконечной). В некоторых задачах удобно наоборот, увеличивать значение параметра при рекурсивном вызове.



Дата добавления: 2018-05-10; просмотров: 1054;


Поиск по сайту:

Воспользовавшись поиском можно найти нужную информацию на сайте.

Поделитесь с друзьями:

Считаете данную информацию полезной, тогда расскажите друзьям в соц. сетях.
Poznayka.org - Познайка.Орг - 2016-2024 год. Материал предоставляется для ознакомительных и учебных целей.
Генерация страницы за: 0.007 сек.