Библиотека Рефераты Курсовые Дипломы Поиск
Библиотека Рефераты Курсовые Дипломы Поиск
сделать стартовой добавить в избранное
Кефирный гриб на сайте za4eti.ru

Компьютеры, Программирование Компьютеры, Программирование

Рекурсия

Крючки с поводками Mikado SSH Fudo "SB Chinu", №4BN, поводок 0,22 мм.
Качественные Японские крючки с лопаткой. Крючки с поводками – готовы к ловле. Высшего качества, исключительно острые японские крючки,
58 руб
Раздел: Размер от №1 до №10
Ночник-проектор "Звездное небо, планеты", черный.
Оригинальный светильник-ночник-проектор. Корпус поворачивается от руки. Источник света: 1) Лампочка (от карманных фанариков); 2) Три
350 руб
Раздел: Ночники
Гуашь "Классика", 12 цветов.
Гуашевые краски изготавливаются на основе натуральных компонентов и высококачестсвенных пигментов с добавлением консервантов, не
170 руб
Раздел: 7 и более цветов

СодержаниеРекурсия . . . . . . . . . . . . . . . . . . . . . . . . . . 2Пример 1 . . . . . . . . . . . . . . . . . . . . . . . . . . 2Пример 2 . . . . . . . . . . . . . . . . . . . . . . . . . . 3Пример 3 . . . . . . . . . . . . . . . . . . . . . . . . . . 4Пример 4 . . . . . . . . . . . . . . . . . . . . . . . . . . 4Пример 5 . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Рекурсия. Рекурсией называется ситуация, когда процедура или функция сама себя вызывает. Вот типичная конструкция такого рода: procedure proc(i:i eger); begi a weisu ge 1; if bedi gu g he proc(i 1); a weisu ge 2; e d;Вызов proc(1) означает, что proc вызывает себя раз за разом с помощью proc(2), proc(3),. до тех пор, пока условие bedi gu g не отменит новый вызов. При каждом вызове выполняется оператор a weisu ge 1, после чего порядок выполнения операторов прерывается новым вызовом proc(i 1). Чтобы для каждого вызова был отработан и оператор a weisu ge 2, все локальные переменные процедуры сохраняются в стеке. Стеком является структура магазинного типа LIFO (Las I Firs Ou ), т.е. если, например, при proc(10) условие более не выполняется, a weisu ge 2 выполняется со значениями, обрабатываемыми в обратном порядке для proc(9), ,proc(1). Локальные параметры помещаются в стек один за другим и выбираются из стека в обратной последовательности (латинское recurrere означает «возвращение назад»). В Паскале можно пользоваться именами лишь тогда, когда в тексте программы этому предшествует их описание. Рекурсия является единственным исключением из этого правила. Имя proc можно использовать сразу же, не закончив его описания. Пример1 представляет собой бесконечную рекурсию, с помощью которой можно установить, насколько велик стек. При этом помните, что при использовании директивы ( $S ) при переполнении стека получим сообщение об ошибке; а при использовании директивы ( $S- ) – нет, а значит, мы скорее всего столкнемся с зависанием системы. Установкой по умолчанию является ( $S ). Программа будет прервана с выдачей сообщения об ошибке «Error 202: s ack overflow error (“Ошибка 202: переполнение стека»). Пример1: Program s ack es ; {программа проверки стека} procedure proc(i:i eger); begi if i mod 1024 = 0 he wri el (i:6); proc(i 1); e d; begi proc(1); e d. Стек связан с другой структурой памяти – с динамической областью. С помощью директивы ( $М ) можно управлять размером стека. Рекурсия не должна восприниматься как некий программистский трюк. Это скорее некий принцип, метод. Если в программе нужно выполнить что-то повторно, можно действовать двумя способами: - с помощью последовательного присоединения (или итерации в форме цикла); - с помощью вложения одной операции в другую (а именно, рекурсий). В следующем примере2 один раз счет от 1 до ведется с помощью цикла, а второй – с помощью рекурсии. При этом хорошо видно, как заполняется, а затем освобождается стек. В процедуре rekursio операция wri el (i:30) выполняется перед рекурсивным вызовом, после чего wri el (i:3) освобождает стек. Поскольку рекурсия выполняется от до 1, вывод по команде wri el (i:30) выполняется в обратной последовательности , -1, ,1, а вывод по команде wri el (i:3) – в прямой последовательности 1,2, , (согласно принципу LIFO – последним пришел, первым обслужен).

Пример2: Показывает принципиальное различие между итерацией и рекурсией: итерации необходим цикл и локальная переменная k как переменная цикла. Рекурсии ничего этого не требуется! program i era iv zu rekursio ; var :i eger; procedure rekursio (i:i eger); begi wri el (i:30); if i < 1 he rekursio (i-1); wri el (i:3); e d; ( Рекурсия ) procedure schleife(i:i eger); var k:i eger; bagi k :=1; while k 1 he co ver (z div 8); ( Это рекурсивный вызов ) wri e(z mod 8:1); e d; begi wri el (‘Введите некоторое положительное число:’); readl (z); wri el (‘Десятичное число:’,z:6); wri e(‘Восьмеричное число: ’); co ver (z); e d. Один из наиболее ярких примеров применения рекурсии дают числа Фибоначчи. Они определяются следующим образом: x при > 2 Каждый элемент ряда Фибоначчи является суммой двух предшествующих элементов, т.е. 1 1 2 3 5 8 13 21 34 55 Следующий пример позволяет вычислить -ный элемент ряда Фибоначчи как итеративно (то есть в цикле, начиная с х), так и рекурсивно ( - ный элемент ряда является суммой двух предшествующих элементов). Причем рекурсивная функция вызывает себя дважды. Пример4: С использованием рекурсии вычисляются числа Фибоначчи, причем глубина рекурсии индицируется. Перед каждым рекурсивным вызовом выводится выводиться ASCII-символ с номером 8 (Backspace), а после вызова вновь стирается. Тем самым можно наблюдать за работой программы, поскольку программа за счет delay(300) приостанавливается на 0.3 с. program fibo acci(i pu , ou pu ); uses cr ; var ,resul :i eger; fu c io fibi ( :i eger):i eger; var a,b,c,i:i eger; begi a := 1; b := 1; if ( =1) or ( =2) he fibi :=1 else begi for i= 3 o do begi c :=a b; a := b; b :=c; e d; fibi :=c; e d; e d; begi clrscr; wri e(‘ = ‘); readl ( ); wri el (‘Итеративно:’,fibi ( ):5); wri el (‘рекурсивно:’); wri e(‘ .! .# .! .# .’); wri el (‘! .# .! .# .! .#’); wri e (‘Глубина рекурсии:’); resul := fibrek( ); wri el ; wri e(resul ); e d. Этот пример демонстрирует прежде всего различия между итерацией и рекурсией. Итерации необходим цикл и вспомогательные величины; итерация сравнительно ненаглядна (см. fibi в приведенном выше примере). Рекурсия обходится без вспомогательных величин и обычно проще для понимания, что демонстрирует следующая запись: if ( =1) or ( =2) he fibrek := 1 else fibrek := fibrek( -1) fibrek( -2); Итерация требует меньше места в памяти и машинного времени, чем рекурсия, которой необходимы затраты на управление стеком. Итак, если для некоторой задачи возможны два решения, предпочтение следует отдать итерации. Правда, для многих задач рекурсивная формулировка совершенно прозрачна, в то время как построение итерации оказывается весьма сложным делом. Если процедура или функция вызывает себя сама, это называют прямой рекурсией. Но может встретиться ситуация, когда процедура А вызывает процедуру В, вызывающую С, а процедура С вновь возвращается к А. В этом случаи мы имеем дело дело с косвенной рекурсией, что демонстрирует приведенный ниже пример. С таким типом рекурсии мы сталкиваемся там, где использована директива forward. Пример 5: Следующая программа выдает простые числа от 1 до , для чего используются функции ex и prim, которые вызываются перекрестно, то есть рекурсивно.

Одновременно это является примером применения директивы forward. program primzahle rekursiv berech e ; {программа рекурсивного вычисления простых чисел} var ,i : i eger; c : char; fu c io ex (i:i eger):i eger;forward; {Это прямая ссылка вперед на функцию ex , которая будет определена позже} fu c io prim(j:i eger):boolea ; {prim имеет значение rue, если j простое число, и false в противном случае} var k:i eger; begi k :=2; while (k k 0) do k := ex (k); {k пробегает последовательность простых чисел, начиная с 2, вплоть до корня из j, при этом проверяется, делится ли j на одно из таких простых чисел. При этом используется следующая функция ex } if j mod k = 0 he prim := false else prim := rue; e d {prim}; fu c io ex ; {Параметры уже стоят в ссылке вперед, ex вычисляет, каково следующее за j простое число} var i:i eger; begi 1 :=i 1; while o (prim(1)) do 1 :=1 1; {Итак, ex вызывает в свою очередь prim} ex :=1; e d { ex }; begi ( Исполняемая часть программы ) wri e(‘Введите положительное число ,’); wri el (‘Должны быть определены все’); wri el (‘предшествующие ему простые числа’); readl ( ); for i :=2 o do begi if prim(i) he wri el (i:14) else wri el (i:4); if i mod 23 = 0 he begi wri e(‘’:60); read(c,c); e d; e d; e d.

Например: main() (* employee e; e.name = «Дж.Браун»; e.department = 1234; e.next = 0; manager m; m.name = «Дж.Смит»; e.department = 1234; m.level = 2; m.next = amp;e; f( amp;m); *) выдаст Дж.Смит 1234 уровень 2 Дж.Браун 1234 Заметьте, что это будет работать даже в том случае, если f() была написана и откомпилирована еще до того, как проиводный класс manager был задуман! Очевидно, при реализации этого в каждом объекте класса employee сохраняется некоторая информация о типе. Занимаемого для этого пространства (в ткущей реализации) как раз хватает для хранения указателя. Это пространство занимается только в объектах классов с виртуалными функциями, а не во всех объектах классов и даже не во всех объектах производных классов. Вы платите эту пошлину только за те классы, для которых описали виртуальные функции. Вызов функции с помощью операции разрешения области вдимости ::, как это делается в manager::print(), гарантирует, что механизм виртуальных функций применяться не будет. Иначе manager::print() подвергалось бы бесконечной рекурсии

1. Рекурсия

2. Рекурсия

3. Рекурсия


Поиск Рефератов на сайте za4eti.ru Вы студент, и у Вас нет времени на выполнение письменных работ (рефератов, курсовых и дипломов)? Мы сможем Вам в этом помочь. Возможно, Вам подойдет что-то из ПЕРЕЧНЯ ПРЕДМЕТОВ И ДИСЦИПЛИН, ПО КОТОРЫМ ВЫПОЛНЯЮТСЯ РЕФЕРАТЫ, КУРСОВЫЕ И ДИПЛОМНЫЕ РАБОТЫ. 
Вы можете поискать нужную Вам работу в КОЛЛЕКЦИИ ГОТОВЫХ РЕФЕРАТОВ, КУРСОВЫХ И ДИПЛОМНЫХ РАБОТ, выполненных преподавателями московских ВУЗов за период более чем 10-летней работы. Эти работы Вы можете бесплатно СКАЧАТЬ.