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

7.5. Рекурсия и рекурсивные вычисления

Рассмотрим функции F(n), зависящие от некоторого параметра, принимающего целые значения из натурального ряда: n= 1,2,… Примерами таких функций являются числовые последовательности. Если формула, выражающая величину n-го члена последовательности F(n) через значение параметра n при помощи алгебраических функций существует, то говорят, что последовательность (функция) задана явно.

Пример 1. Классические явно заданные функции от целого аргумента:

1) возведение в степень: аn = a a a a (n раз),

2) факториал: n! = n (n-1) (n-2) 2 1,

3) арифметическая прогрессия: S(n) = a1+ d (n-1),

4) геометрическая прогрессия: S(n) = a1 qn-1.

Однако общая формула для члена последовательности F(n) не всегда может быть задана в достаточно удобной форме. Зачастую формулу для F(n) проще задавать в рекуррентном виде, когда величина F(n) выражена через значение F(n-1) для предыдущего натурального значения параметра, равное (n-1). Практически значение F(n) может быть выражено не только через F(n-1), но и, возможно, через F(n-2),F(n-3) и т.д. При выполнении подстановок вида F(n) через F(n-1) с уменьшающимся значением параметра n в конце концов всегда возникает необходимость расчета F(1) для начального значения параметра n=1. Поскольку для него нет более младшего значения параметра, то значение F(1) должно быть задано постоянной величиной, уже не требующей рекурсии для вычисления. Если в зависимость для F(n) входят не одно, а несколько значений функций с младшими значениями параметра, то должно быть задано столько же начальных значений. Совокупность начальных значений последовательности и функциональной зависимости F(n) = F(n)(F(n-1)) = r(F(n-1)) называют рекуррентной формулой числовой последовательности (функции).

Примеры 2 рекуррентного задания числовых последовательностей:

1) x1 = 3, xn+1 = 4xn + 1 - числовая последовательность 3, 13, 53, 213, 853, ...,

2) x1 = 0, x2 = 1, xn+2 = xn+1 + xn - числовая последовательность, называемая “числа Фибоначчи”, члены которой равны 0, 1, 1, 2, 3, 5, 8, 13, 21, …

К рекуррентному виду могут быть приведены и функции с явным заданием. Примеры 3 рекуррентного задания функций, явно заданных в примере 1:

1) возведение в степень: F(1)= a; F(n) = F(n-1) a, (n≥2),

2) факториал: F(1)=1; F(n) = F(n-1) n, (n≥2),

3) арифметическая прогрессия: F(1)= a0; F(n) = F(n-1) + d, (n≥2),

4) геометрическая прогрессия: F(1)= a0; F(n) = F(n-1) q , (n≥2).

Замечание. В качестве начального значения целочисленного параметра функции F(n) могут быть приняты не только n=1, но и другие значения параметра. Помимо n=1 чаще всего начальным значением принимают n=0, когда параметр n принимает все значения из расширенного натурального ряда {0,1,2,…}.

При переходе от явного задания числовой функции F(n) к рекурсивному необходимо по ее общему виду определить вид зависимости F(n) = r(F(n-1)) и подстановкой в F(n) начального значения параметра n=1 (или иного - в зависимости от решаемой задачи) определить начальное значение функции F(1).

Примеры 4. Найти рекуррентную форму для явно заданной функции:

Решение. Для определения искомой зависимости F(n) = r(F(n-1)) рассмотрим частное:

F(n) / F(n-1) = (n2 + 2n - 3).

Из него следует, что искомая формула имеет вид: F(n) = (n2 + 2n - 3) F(n-1) .

Определим значение функции при начальной величине параметра. Так как самое малое значение равно 0, то

Таким образом, искомая рекуррентная форма функции имеет вид:

F(0) = -3; F(n) = (n2 + 2n - 3) F(n-1) при (n > 0).

Рекурсией называется такой способ вычисления значений функции, при котором функция вызывает саму себя. Различают прямую и косвенную рекурсии.

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

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

Рассмотрим, как практически выполняется рекурсивный вызов функции F. По общему алгоритму вызова подпрограмм, запоминается текущее состояние программы, необходимое для продолжения вычислений, когда управление снова вернется к ней. Затем F начинает выполняться с новыми значениями аргументов и как бы новым экземпляром программы. При следующем рекурсивном вызове F всё повторяется снова до тех пор, пока очередной вызов F не приводит к начальному значению параметра, для которого значение функции задается явно в виде числа. При каждом рекурсивном вызове создается новое множество локальных переменных, т.е. переменные, расположенные вне вызываемой функции, не изменяются. После этого в порядке, обратном тому, в котором запоминалась серия прямых вызовов, производятся возвраты управления.

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

Классическим примером рекурсивной функции является расчет факториала натурального числа n! = n (n-1) (n-2) 2 1, рекуррентная формула которого задана в строке 2) примера 3.

Пример 5. Программный код рекурсивной функции, вычисляющей факториал числа n:

function factorial (n : integer): integer;

begin

if n=1 then factorial:=1 else factorial:=n*factorial(n-1); {функция factorial(n) вызывает factorial( n -1 ) - саму себя}

end;

Пример 6. Программный код рекурсивной функции, вычисляющей числовую последовательность с рекуррентной формулой x1 = 3, xn+1 = 4xn + 1 (строка 1 примера 2).

function seq (n : integer): integer;

begin

if n=1 then seq:=3 else seq:=4*seq(n-1)+1; {функция seq(n) вызывает seq( n -1)}

end;

Пример 7. Программный код рекурсивно заданной функции из примера 4: F(0) = -3; F(n) = (n2 + 2n - 3)  F(n-1) при (n > 0).

function r_fun (n : integer): integer;

begin

if n=0 then r_fun:=-3 else r_fun:=(n*n+2*n-3)*r_fun(n-1);

end;

Вопросы для проверки знаний.

1. Какой способ задания числовых функций называют явным, а какой - рекуррентным ?

2. Что называют рекуррентной формулой числовой последовательности (функции) ?

3. Почему при задании рекурсии необходимо самое первое значение функции вводить присваиванием ?

4. Какой способ вычисления значений функций называют рекурсией ?

5. Может ли параметр числовой функции начинаться не со значения, равного 1 ?

6. Что необходимо определить при переходе от явного способа задания функции к рекуррентному ?

7. Какие функции называют прямо рекурсивными, а какие - косвенно рекурсивными ?

8. Как практически выполняется рекурсивный вызов функции, почему при его использовании необходимо учитывать емкость стека ?

Практическое задание.

1. Разработать код рекурсивной функции, выполняющей возведение вещественного числа в целую степень.

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