Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Шпоры ОАиП(теория).docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
151.01 Кб
Скачать

21. Рекуррентные выражения. Рекурсия: прямая и косвенная.

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

С понятием рекурсии мы уже встречались при рассмотрении алгоритма Хоара. Вообще это понятие относится не только к алгоритмам. В жизни возникают рекурсивные изображения (в зеркале, на телеэкране). При описании синтаксиса какого-либо языка часто используются металингвистические формулы (Бэкуса нормальные формы), например:

<цифра> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |,

<буква> ::= A| B | …| Z,

<целое число без знака> ::= <цифра> | <целая часть><цифра>,

<идентификатор>::=<буква>|<идентификатор><буква> | <идентификатор><цифра>.

Две последние формулы рекурсивны.

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

1 при n=0,

n! = {

n*(n-1)! при n>0.

Достоинства и недостатки рекурсивных программ.

Любое рекурсивное определение функции можно заменить нерекурсивным. Точно также и любой рекурсивный алгоритм можно заменить нерекурсивным. Так для вычисления n! нерекурсивная функция будет описана следующим образом:

FUNCTION FACT (N: INTEGER): INTEGER;

VAR K,I: INTEGER;

BEGIN

K:=1;

FOR I:=1 TO N DO K:=K*I;

FACT:=K;

END;

Рекурсивность – это не свойство функции, а свойство ее описания. Какое же из описаний лучше?

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

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

Если в алгоритме мало действий, то доля дополнительных команд может оказаться слишком большой. Например, в алгоритме для n! рекурсивная процедура гораздо медленнее, поэтому целесообразнее использовать его нерекурсивную форму, а именно – итеративную (рекуррентную).

Поэтому вывод можно сделать следующий. Если задача имеет очевидное итеративное решение, то рекурсии следует избегать. Однако это не значит, что от рекурсии нужно избавляться всегда и любой ценой. Для алгоритма Хоара, например, потери во времени на практике являются небольшими. Многие сложные алгоритмы описываются в рекурсивной форме более наглядно, поэтому целесообразно их описывать именно так.

Примеры рекурсивных процедур и функций.

Язык Паскаль позволяет создавать процедуры и функции, обладающие свойством рекурсивности, то есть содержащие в своем описании вызов самих себя. Так для вычисления n! мы можем составить такое рекурсивное описание функции.

Пример 1.

FUNCTION FACT (N: INTEGER): INTEGER;

BEGIN

IF N=0

THEN FACT:=1

ELSE FACT:=N*FACT(N-1)

END;

Пример 2.Выдать на печать в обратном порядке цифры целого положительного числа N.

PROCEDURE REVERSE (N: INTEGER);

BEGIN

WRITE (N MOD 10);

IF (N DIV 10)> 0

THEN REVERSE (N DIV 10)

END;