Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
4 основи програмування книга.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
1.77 Mб
Скачать

9.2. Приклади рекурсивних описів процедур і функцій

Декілька прикладів рекурсивних процедур, розглянутих у цьому пункті, допоможуть кращому засвоєнню техніки застосування рекурсії. Ми також побачимо переваги і недоліки рекурсивних описів.

Приклад 9.3. Повернені послідовності.

Розглянемо послідовність V(n), що задана рекурентно:

1.V(0) = V0, V(1) = V1, ..., V(k) = Vk;

2.V(n+k) = F( V(n+k-1), ... V(n+1), V(n), n )

Таке визначення задає послідовність V(n) фіксуванням перших її декількох членів і функції F, що обчислює кожний наступний член, виходячи з попередніх. Рекурентне визначення “дослівно переводиться” в функцію, що обчислюється рекурсивно:

Function V(n: Integer) : Integer;

Begin

Case n of

0: V := V0;

. . . . .

k: V := Vk

else V := F(V(n+k-1), ... V(n+1), V(n), n)

end

End;

Один з прикладів повернених послідовностей – послідовність Фібоначчі, програму обчислення якої ми вже розглядали. Ось її рекурсивна версія:

Function RF(n: Integer) : Integer;

Begin

Case n of

0,1: RF := 1

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

end

End;

Нажаль, це рішення вкрай неефективне: Можна довести, що

Tr f (n) > 2 n-2 при n>5.

Таким чином, складність обчислення RF(n) експоненціальна. Складність же ітеративного алгоритму обчислення Fib лінійна. У загальному випадку ситуація точно така ж: можна побудувати ітеративний алгоритм обчислення поверненої послідовності лінійної складності, рекурсивна ж версія при k>=1 має експоненціальну складність.

Приклад 9.4. Ханойські башти

Класичний приклад застосування рекурсії для описання ефективного алгоритму – задача про ханойські башти. На перший з трьох стержнів, закріплених вертикально на підставці, насаджено декілька кілець різних діаметрів так, що кільце меншого діаметра лежить на кільці великого діаметра. Два інших стержня порожні (рис. 9.1).

У задачі треба переставити всі кільця з 1-го стержня на 2-ий за декілька кроків. Кожний крок – це перестановка верхнього кільця одного стержня на верхнє кільце іншого стержня з дотриманням правила: діаметр кільця, що переставляється повинен бути менше, ніж діаметр кільця, на яке здійснюється перестановка.

Рис. 9.1

Нехай N – кількість кілець на стержні, І – номер кільця, з якого здійснюється перестановка і J – номер кільця, на який кільця треба переставити. Змінні N,I,J - параметри процедури HanojTower, керуючої перестановками. Крок розв’язку – процедура Step з параметрами I, J.

HanojTower (N,I,J) - процедура, що переставляє N кілець з I-того стержня на J-тий.

Step (I, J) - процедура , що переставляє 1-не кільце з I-того стержня на J-тий.

Відмітимо, що якщо I і J - номера 2-стержней, то 6-I-J - номер третього стержня.

Припустимо, що ми перемістили N-1 кільце з I-того стержня на 6-I-J стержень. (рис. 9.2)

Рис. 9.2

(n-1) кільце

I стержень j стержень 6-I-j стержень

Тоді можна перемістити кільце з стержня I на J. (рис. 9.3)

Рис. 9.3

1 кільце