Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по информатике.doc
Скачиваний:
118
Добавлен:
02.05.2014
Размер:
1.53 Mб
Скачать

Рекурсия

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

Рекурсивной функцией называется функция, которая для выполнения определенной операции вызывает саму себя. Процесс вызова функцией самой себя называется рекурсией. По мере возрастания сложности программ и функций может оказаться, что при определении некоторых операций удобно использовать сами эти операции. В таких случаях имеет смысл создавать рекурсивные функции. Классическим примером рекурсивной обработки является вычисление факториала. Факториал значения 1 равен 1. Факториал значения 2 равен 2*1. Факториал значения 3 равен 3*2*1. Аналогично, факториал значения 4 равен 4*3*2*1. Этот процесс может быть продолжен до бесконечности. Если внимательно приглядеться к процессу вычисления факториала, то можно увидеть, что факториал, например, от 4 равен 4-кратному значению факториала от 3 (3*2*1). Аналогично, факториал от 3 равен 3-кратному значению факториала от 2 (2*1). Факториал от 2 равен двукратному значению факториала от 1 (1). В таблице демонстрируется вычисление факториала.

Таблица. Вычисление факториала

Значение

Вычисление

Результат

Факториал

1

1

1

1

2

2*1

2

2*Factorial(l)

3

3*2*1

6

3* Factorial(2)

4

4*3*2*1

24

4* Factorial(3)

5

5*4*3*2*1

120

5* Factorial(4)

В следующей программе представлена рекурсивная функция factorial, которая используется для вычисления факториала значений от 1 до 5:

#include <stdio.h>

int factorial (int value)

{

if (value ==1)

return(1);

else

return(value * factorial(value-1));

}

void main(void)

{

int i;

for (i =1; i <= 5; i++)

printf("Факториал от %d равен %d\n", i, factorial(i));

}

Как можно видеть, функция factorial возвращает значение, которое основывается на результате вызова самой этой функции.

При выполнении этой функции первым делом осуществляется проверка значения параметра на равенство 1. Если значение равно 1, то функция возвращает 1. В противном случае, в качестве результата возвращается значение, равное произведению значения входного параметра и факториала от числа, равного значению параметра минус 1. Например, предположим, что функция вызывается со значением 3. Тогда в качестве результата функцией будет возвращено 3*factorial(3-1). Обнаруживая в операторе return вызов функции factorial, компилятор организует повторный вызов, на этот раз со значением 3-1 или 2. Поскольку значение не равно 1, результатом выполнения функции будет 2*factorial(2-1). Наконец, при следующем вызове функции значение параметра равно 1, поэтому в качестве результата вызвавшей программе (функции) возвращается значение 1.

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

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