Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Пример 51

Пример

Исходные данные: N - целое неотрицательное число.
Результат: факториал числа N

 

program FactorRec; {вычисление факториала с использованием рекурсии} var N: integer; function Factor(N: integer): integer; begin if N = 0 then Factor:= 1 else Factor:= N * Factor(N-1); end; begin {начало программы} writeln('введите целое число'); read(N); writeln('Факториал ', N:4, '=', Factor(N)); end.

 

С помощью выражения Factor(N-1) эта функция будет вызывать сама себя до тех пор, пока значение параметра не станет равным 0. При каждом повторном вызове функции создается новый экземпляр памяти для всех локальных переменных и для самой функции, который запоминается в стеке. Пусть N = 4, тогда в результате выполнения функции Factor будет создан стек, представленный на Рис.9. Этот процесс называется процессом развертывания рекурсии.

Рис. 9. Процесс развертывания рекурсии

Как только N становится равным 0, вычисляется первое значение факториала Factor = 1, которое затем подставляется в соответствующий экземпляр памяти. Теперь на каждом очередном шаге значения всех членов выражения N * Faсtor(N - 1) известны и алгоритм подставляет в это выражение значение, полученное на предыдущем шаге. Начинается процесс свертывания рекурсии, представленный на Рис.10, и вычисляется значение Factor = 24.

Рис. 10. Процесс свертывания рекурсии

Отметим, что вычисление выражения в процессе свертывания рекурсии осуществляется с запомненным значением N, поскольку N передается в функцию по значению (без параметра Var). Так, на 4-м шаге в выражение подставляется значение Factor (0)=1 и N = 1, на 3-м шаге - Factor (1) = 1 и N = 2 и т.д.
Для сравнения приведем программу в примере 51, где рекурсия заменяется обычной итерацией.

program FactorIt; {вычисление факториала с использованием итерации} var F, N, I: integer; begin writeln('Введите целое число '); read(N); F:= 1; for I:= 1 to N do F:= F * I; writeln('Факториал', N:4, '=', F); end.

 

Бесспорно, что реализация вычисления факториала в примере 51 является более традиционной, однако в этом случае используется три переменных.

Сформулируем свойства рекурсивных алгоритмов:

1. Наличие тривиального случая.
Правильный рекурсивный алгоритм не должен создавать бесконечную последовательность вызовов самого себя. Для этого он обязательно должен содержать нерекурсивный выход, т.е. при некоторых исходных данных вычисления в алгоритме должны производиться без вызовов его самого - тривиальный случай. Примером тривиального случая в рекурсивном алгоритме вычисления N! является условие N = 0.
2. Определение сложного случая в терминах более простого.
При любых исходных данных нерекурсивный выход должен достигаться за конечное число рекурсивных вызовов. Для этого каждый новый вызов рекурсивного алгоритма должен решать более простую задачу, т.е. рекурсивный алгоритм должен содержать определение некоторого сложного случая в терминах более простого случая. В случае вычисления факториала - это вычисление по формуле N! = N * (N-1)!, где N уменьшается при каждом рекурсивном вызове.

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

 

 

<== предыдущая лекция | следующая лекция ==>
Сравнение рекурсии и итерации | Технологии микробного выщелачивания
Поделиться с друзьями:


Дата добавления: 2014-01-04; Просмотров: 253; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.012 сек.