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

У попа была собака. Он ее любил.

Она съела кусок мяса, он ее убил.

И на могиле написал:

«У попа была собака…

Лекция 9. Рекурсия Введение

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

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

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

Доказывая теорему неиндуктивным методом, математик использует логи­ческие рассуждения, опираясь на другие теоремы и аксиомы.

При доказательстве теоремы методом математической индукции он должен предположить, что доказываемая теорема справедлива при «меньшем» значении параметра индукции и, опираясь на это предположение, доказать теорему для данного значения параметра индукции. Обоснование законности такого способа рассуждений берет на себя математика (Метод мате­матической индукции – один из общематематических законов – постулатов математики).

Необходимость использовать описываемый алгоритм для своего собствен­ного описания часто приводит к чис­­то психологическим затруднениям. Возникает законный воп­рос: нужны ли рекур­сив­ные описания вообще?

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

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

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

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

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

Технология программирования на языках проце­ду­р­ного программирования (типа языка Паскаль) предла­гает проекти­ровать программы методом последо­ва­тельных уточнений.

Концепция процедур и функций (подпрограмм) позволяет выделить подзадачу как явную подпрограмму и оформить ее в виде процедуры или функции. Таким образом, программа представляет собой структуру, элементами которой являются процедуры и функции – основные семантические единицы программы.

В частности, в качестве подзадачи может фигу­ри­ро­вать и исходная задача с измененными исход­ными данны­ми (задача «меньшего размера»).

Пример 1.

Поиск минимального элемента в последо­ва­тельности

a1, a2, .., ak, ak+1,.., an

можно организовать как

  1. поиск минимального элемента b1 в a1, a2, .., ak ;

  2. поиск минимального элемента b2 в ak+1, ak+2, .., an ;

  3. выбор наименьшего элемента b из двух найденных (b1, b2).

Основная идея состоит в том, чтобы разбить последова­тель­ность на две части a1, a2, .., ak и ak+1, ak+2, .., an , применить описываемый метод к каждой из этих частей, а затем выбрать наименьший элемент из двух найденных. Такие алгоритмы называют рекурсивными.

Описание процедуры (функции) P, в разделе опера­торов которой используется оператор этой процедуры (вызов функции), называется рекурсивным.

Рис. 1. Схема простой рекурсии

Использование рекурсивного описания процедуры (функ­ции) приводит к рекурсивному выполнению этой процедуры (вычислению этой функции).

Пример 2. Факториал.

Рассмотрим рекурсивное определение факториала натурального числа n - функции n! = 1*2*...*n. Пусть F(n) = n!! Тогда

1.F(0) = 1

2.F(n) = n*F(n - 1) при n > 0

Средствами языка это определение можно сформу­ли­ровать как вычисление:

If n = 0

then F := 1

else F := F(n - 1) * n

Оформив это вычисление как функцию, получим:

Function F(n: Integer): Integer;

Begin

If n = 0

then F := 1

else F := F(n - 1) * n

End;