русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Рекурсия


Дата добавления: 2013-12-23; просмотров: 1781; Нарушение авторских прав


Встречаются задачи, в которых подпрограмма вызывает саму себя. Это называется рекурсией. Таким образом можно организовать хитрые циклы, которые иным способом либо очень трудно, либо невозможно сделать. Например, процедура KRUG рисует круг, состоящий из кругов, которые в свою очередь состоят из кругов и т.д… Ёлочка – это большая ветка, состоящая из веток, которые состоят из веточек… Любые самоповторяющиеся рисунки (фракталы) создаются с помощью рекурсии. Но не только рисунки. С помощью рекурсии работает процедура закраски (в начальной позиции ставится точка, которая ставит точки вокруг себя, а те в свою очередь ставят точки вокруг них… и т.д., пока не будет достигнута граница). С помощью рекурсии можно найти кратчайший путь к выходу из лабиринта, экономно раскроить заготовку на детали и т.д. Одним словом, если встречается сложная задача, которую вроде бы решить нужно циклом, но непонятно, как его организовать – попробуйте рекурсию! Приведём пример:

Нарисовать с использованием рекурсии ёлочку.

program elka; uses graphabc; var gd,gm:integer; procedure vetka(x,y,alf,dl:real); var xk,yk,dx,dy:real; i:integer; begin xk:=x+dl*sin(alf); yk:=y-dl*cos(alf); line(round(x),round(y),round(xk),round(yk)); if dl<15 then exit; {Условие окончания рекурсии} dx:=(xk-x)/8; dy:=(yk-y)/8; for i:=1 to 8 do begin vetka(x+i*dx,y+i*dy,alf-pi*0.35,dl*(0.5-i*0.06)); vetka(x+i*dx,y+i*dy,alf+pi*0.35,dl*(0.5-i*0.06)); end; end; begin setwindowsize(700,500); vetka(320,450,0,400); end.  

 

 

 

Находим координаты (xk, yk) конца веточки и проводим отрезок из начала в конец. Затем делим ветку на 8 частей (находим шаги dx и dy) и в этих точках рекурсивно вызываем процедуру «ветка», задавая ей другие углы (влево и вправо от ветки на π*0.35) и уменьшенную длину.



Должно получиться нечто следующее:

Использование рекурсии опасно зависанием. В примере с ёлочкой каждая следующая веточка вызывается меньших размеров. Но так может продолжаться до бесконечности (а точнее, до переполнения памяти), если процесс уменьшения не остановить. В данном примере мы прекращаем рекурсивный вызов, если длина очередной веточки становится меньше 15 пикселов. (Можно сделать ограничение в 1 пиксел, но тогда иголки будут короткими). На этом примере можно сформулировать правило безопасной рекурсии: В рекурсивной процедуре проверку условия окончания рекурсии нужно выполнять ДО рекурсивного вызова.

Кроме прямой рекурсии, о которой рассказано выше, существует ещё косвенная рекурсия: подпрограмма A вызывает подпрограмму B, которая в свою очередь вызывает A … Например, круг, который состоит из квадратов, которые состоят из кругов… Здесь возникает такая проблема: одна из этих подпрограмм, например, A, описана выше и не знает о существовании подпрограммы B, которая описана ниже, следовательно, не может к ней обратиться. Для решения такой проблемы в Паскале предусмотрен механизм предварительного описания. Заголовок (только!) подпрограммы B копируют до подпрограммы A, а в конце этого заголовка после точки с запятой добавляют слово forward. Это слово показывает Паскалю, что это ещё не описание подпрограммы, а только прототип, предварительное оповещение.


 



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


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

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