Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
LektsiiS.doc
Скачиваний:
81
Добавлен:
13.04.2015
Размер:
815.1 Кб
Скачать

5 Рекурсивные алгоритмы

5.1 Простая рекурсия

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

Вспомним алгоритм двоичного поиска из раздела 3.

Начало

Установить левую границу области поиска, Left = 1;

Установить правую границу области поиска, Right = n;

Пока левая граница не больше правой, Left <= Right, повторять

Начало

Найти середину области поиска, Middle = (Left + Right) / 2;

Если X < M[Middle], то

изменить правую границу, Right = Middle-1;

Если X > M[Middle], то

изменить левую границу, Left = Middle+1;

Если X = M[Middle], то

вывести значение Middle и закончить работу;

Конец

Сообщить, что числа X в массиве нет

Конец

Сформулируем его в рекурсивной форме.

Процедура Двоичный Поиск (Left, Right)

Начало

Еслилевая граница не больше правой, Left <= Right,то

Начало

Найти середину области поиска, Middle = (Left + Right) / 2;

Если X < M[Middle],тоДвоичныйПоиск (Left, Middle-1);

ЕслиX > M[Middle],тоДвоичныйПоиск (Middle+1, Right);

Если X = M[Middle],товывести значение Middle;

Конец иначе сообщить, что числа X в массиве нет;

Конец

Чтобы разыскать число X в массиве M надо выполнить оператор процедуры

Двоичный Поиск (1, n);

где n — количество элементов массива М.

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

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

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

Мы рассмотрели самый простой вид рекурсии, когда в процессе выполнения алгоритм вызывает себя ровно один раз (хотя в алгоритме два оператора процедуры, выполняется всегда лишь один из них). Такой вид рекурсии легко заменяется оператором цикла, и нам он понадобился лишь для знакомства с этим приемом программирования.

5.2 Ханойские башни

Программистам давно известна следующая задача.

З а д а ч а.

Имеется три стержня: 1-й, 2-й и 3-й. На первом стержне находится пирамида из n дисков, внизу — самый большой, на нем — меньший, затем еще меньший и т.д., вверху — самый маленький. Требуется переместить все диски с 1-го стержня на 3-й, перекладывая их по одному таким образом, чтобы ни на каком стержне меньший диск не оказался ниже большего. Говоря точнее, нужно предложить алгоритм такого перемещения.

Р е ш е н и е.

Искомый алгоритм, должен переместить пирамиду с первого стержня на третий, соблюдая известные из условия правила. Поскольку алгоритм будет рекурсивным, нужно заранее позаботиться о его названии и параметрах. Назовем его “Ханой”, а параметрами сделаем 3 числа: N — количество дисков в пирамиде, s — номер стержня-источника и d — номер стержня-приемника:

Процедура Ханой (N, s, d) .

Чтобы переместить пирамиду из N дисков со стержня s на стержень d, используя в качестве промежуточного, пустой стержень m, достаточно сделать следующее.

Начало

Переместить пирамиду из N-1 диска с s на m.

Перенести один оставшийся диск с s на d.

Переместить пирамиду из N-1 диска с m на d.

Конец

Разумеется, все эти действия имеют смысл, если N > 0. Что делать, когда N = 0?

Ответ — ничего. Для переноса пустой пирамиды никаких дисков перекладывать не нужно.

Поскольку мы говорили о перекладывании дисков не с первого стержня на третий, а со стержня s на стержень d, не лишним будет узнать, какой номер у промежуточного стержня. Иными словами, как определить значение m по значениям s и d?

Для этого послужит простая формула: m = 6 - s - d .

И, наконец, как заставить компьютер выполнить пункт 2, т.е. переложить один диск с s на d?

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

Теперь можно переписать решение набело.

Процедура Ханой (N, s, d)

Начало

Если N > 0, то Начало

m = 6 - s - d;

Ханой (N-1, s, m);

Напечатать s и d;

Ханой (N-1, m, d).

Конец

Конец

Чтобы переложить n дисков с первого стержня на третий, надо выполнить оператор процедуры

Ханой (n, 1, 3) .

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]