Скачать презентацию Лекция 6 Итерация и рекурсия Итерация — выполнить Скачать презентацию Лекция 6 Итерация и рекурсия Итерация — выполнить

Л6 Итерация и рекурсия.ppt

  • Количество слайдов: 28

Лекция 6: Итерация и рекурсия Итерация - «выполнить для всех» . Рекурсия – «выполнить Лекция 6: Итерация и рекурсия Итерация - «выполнить для всех» . Рекурсия – «выполнить то же, что и в последний раз» (текущее действие выполняется с помощью предыдущего ответа).

Фракталы – пример рекурсии Треугольник Серпинского Фракталы – пример рекурсии Треугольник Серпинского

Рекурсивным называется любой объект, который частично определяется через себя • Рекурсия — это такой Рекурсивным называется любой объект, который частично определяется через себя • Рекурсия — это такой способ организации вспомогательного алгоритма (подпрограммы), при котором эта подпрограмма (процедура или функция) в ходе выполнения ее операторов обращается сама к себе. Пример рекурсивной процедуры: procedure Rec (a: integer); begin if a>0 then Rec (a-1); writeln(a); end;

procedure Rec (a: integer); begin if a>0 then Rec(a-1); writeln(a); end; procedure Rec (a: integer); begin if a>0 then Rec(a-1); writeln(a); end;

procedure Rec (a: integer); begin if a>0 then Rec(a-1); writeln(a); end; Результат: 0 1 procedure Rec (a: integer); begin if a>0 then Rec(a-1); writeln(a); end; Результат: 0 1 2 3 procedure Rec 2 (a: integer); begin writeln(a); if a>0 then Rec 2 (a-1); end; Результат: ?

Структура описания рекурсивных процедур и функций имеет вид: if <условие> then <оператор> еlse <вызов Структура описания рекурсивных процедур и функций имеет вид: if <условие> then <оператор> еlse <вызов процедуры с другими параметрами>

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

Сложная рекурсия • Уроборос – змей, пожирающий свой хвост. Рисунок из алхимического трактата «Synosius» Сложная рекурсия • Уроборос – змей, пожирающий свой хвост. Рисунок из алхимического трактата «Synosius» Теодора Пелеканоса (1478 г). • Сложная рекурсия

Сложная (косвенная) рекурсия требует опережающего описания procedure B (n: integer); forward; {Опережающее описание второй Сложная (косвенная) рекурсия требует опережающего описания procedure B (n: integer); forward; {Опережающее описание второй процедуры} procedure A (n: integer); {Полное описание процедуры A} begin writeln (n); B(n-1); end; …. procedure B (n: integer); {Полное описание процедуры B} begin writeln (n); if n<10 then A(n+2); end;

procedure B (n: integer); forward; {Опережающее описание второй процедуры} procedure A (n: integer); {Полное procedure B (n: integer); forward; {Опережающее описание второй процедуры} procedure A (n: integer); {Полное описание процедуры A} begin writeln(n); B(n-1); end; procedure B (n: integer); {Полное описание процедуры B} begin writeln (n); if n<10 then A(n+2); end; Результат работы: • Если в основной программе вызвать А(1), или А(2) или …. А(9), то будут выведены числа вида 9 8 10 9 11 10 (для А(9)), 7 6 8 7 9 8 10 9 11 10 (для А(7)) и т. п. • Если вызвать А(10), то будут выведены числа 10 9 11 10 • Если вызвать А(11), то будут выведены числа 11 10 • Если вызвать А(56), то будут выведены числа 56 55 • Если вызвать А(888), то будут выведены числа 888 887

 • Итерация - способ организации обработки данных, при котором определенные действия повторяются многократно, • Итерация - способ организации обработки данных, при котором определенные действия повторяются многократно, не приводя при этом к рекурсивным вызовам программ. • В основе итеративного вычислительного процесса лежит итеративный цикл (While. . , Repeat-Until…, For…) • While <условие цикла> do <тело цикла>;

Пример: Перевод числа в двоичную систему • Получение цифр двоичного числа. Последняя цифра в Пример: Перевод числа в двоичную систему • Получение цифр двоичного числа. Последняя цифра в двоичном представлении равна. . • Взяв целую часть от деления на 2: получим число, имеющее то же двоичное представление, но без последней цифры. Таким образом, достаточно повторять приведенные две операции пока после очередного деления не получим целую часть равную 0. Без рекурсии: while x>0 do begin c: =x mod 2; x: =x div 2; write(c); end; Результат: цифры в обратном порядке

С помощью рекурсии нетрудно добиться вывода в правильном порядке без массива и второго цикла. С помощью рекурсии нетрудно добиться вывода в правильном порядке без массива и второго цикла. procedure Binary. Representation (x: integer); var c: integer; begin {Первый блок. Выполняется в порядке вызова процедур} c : = x mod 2; x : = x div 2; {Рекурсивный вызов} if x>0 then Binary. Representation(x); {Второй блок. Выполняется в обратном порядке} write(c); end;

begin write('Ведите натуральное число в 10 -сс: '); readln(x); procedure Binary. Representation(x: integer); writeln('Переведем begin write('Ведите натуральное число в 10 -сс: '); readln(x); procedure Binary. Representation(x: integer); writeln('Переведем ', x, ' в 2 -сс: '); a: =x; {сохраняем исходное число в Var c: integer; дополнительной переменной а} program Binary. Representations; Var c, x, a : integer; begin {Первый блок. Выполняется в порядке вызова процедур} c : = x mod 2; x : = x div 2; {Рекурсивный вызов} if x>0 then Binary. Representation(x); {Второй блок. Выполняется в обратном порядке} write(c); end; write('1 способ - с помощью итерации (цифры в обратном порядке): '); {цифры двоичного представления вычисляются в обратном порядке (сначала последние)} while x>0 do begin c: =x mod 2; x: =x div 2; write(c); end; write('2 способ - с помощью рекурсии: '); Binary. Representation(a); readkey; end.

Вычисление факториала для n>1, значение факториала может быть вычислено через значение факториала для параметра Вычисление факториала для n>1, значение факториала может быть вычислено через значение факториала для параметра n-1.

Рекурсивная подпрограмма (разными способами) Function Factorial(n: byte): longint; Function Factorial(n: byte): longint; begin if Рекурсивная подпрограмма (разными способами) Function Factorial(n: byte): longint; Function Factorial(n: byte): longint; begin if (n=0) or (n=1) {описываются условия begin if n>0 then Factorial: = Factorial(n-1)*n; { шаг рекурсии } else Factorial: =1 {точка возврата или остановка рекурсии} end; граничных случаев} then Factorial: =1 {точка возврата или остановка рекурсии} else Factorial: =Factorial(n-1)*n; { шаг рекурсии } end;

Вычисление функции Factorial(n) для n=4 В результате вычислений получается, что Factorial(4)=4*3*2*1. Вычисление функции Factorial(n) для n=4 В результате вычислений получается, что Factorial(4)=4*3*2*1.

Соотношение между итерацией и рекурсией: 1. 2. Любой итеративный цикл может быть заменен рекурсией. Соотношение между итерацией и рекурсией: 1. 2. Любой итеративный цикл может быть заменен рекурсией. Рекурсия не всегда может быть заменена итерацией. Различия между итерацией и рекурсией: 1. Итерации необходим цикл и вспомогательные величины. Рекурсия обходится без вспомогательных величин, короче и нагляднее итерации. 2. Итерация требует меньше места в оперативной памяти и меньших затрат машинного времени, чем рекурсия, которой необходимы затраты на управление стеком.

Рекурсия function fact (n: integer): longint; begin if n=0 then fact: =1 else fact: Рекурсия function fact (n: integer): longint; begin if n=0 then fact: =1 else fact: =n*fact(n-1); end; Итерация begin f: =1; for i: =1 to n do f: =f*i; end.

{Функция} {Процедура} Function Fact (N: integer): longint; Begin If N<=1 then Fact: =1 else {Функция} {Процедура} Function Fact (N: integer): longint; Begin If N<=1 then Fact: =1 else Fact: =Fact(N-1)*N Procedure Factorial (N: integer; Var F: longint); Begin If N<=1 then F: =1 else begin Factorial(N-1, F); F: =F*N end End; Вызов из основной программы: x: = Fact(a); writeln( a, ‘!= ', x); Factorial(a, F); writeln( a, ' != ', F); Результат 5!= 120

Пример: Числа Фибоначчи - элементы числовой последовательности, в которой каждое последующее число равно сумме Пример: Числа Фибоначчи - элементы числовой последовательности, в которой каждое последующее число равно сумме двух предыдущих чисел.

Пример рекуррентной последовательности второго порядка - последовательность чисел Фибоначчи а: =1; b: =1; for Пример рекуррентной последовательности второго порядка - последовательность чисел Фибоначчи а: =1; b: =1; for k: =3 tо n do begin c: =a+b; a: =b; b: =c; end;

Итерационный алгоритм нахождения n-го числа Фибоначчи program fibonacci; Var n, f, a, b, c, Итерационный алгоритм нахождения n-го числа Фибоначчи program fibonacci; Var n, f, a, b, c, k: integer; begin writeln (‘Введите число n'); readln ( n ); a: =1; b: =1; for k: =3 to n do begin c: =a+b; a: =b; b: =c end; f: =c; writeln (n, '-й член последовательности Фибоначчи равен ', f); end.

Пример демонстрирует различия между итерацией и рекурсией program fibonacci; var n, result: integer; function Пример демонстрирует различия между итерацией и рекурсией program fibonacci; var n, result: integer; function fibit(n: integer): integer; var a, b, c, i: integer; begin a : = 1; b : = 1; if (n=1) or (n=2) then fibit : =1 else begin for i: = 3 to n do begin c : =a+b; a : = b; b : =c; write (c, ' '); end; fibit : =c; end; function fibrek(n: integer): integer; begin if (n=1) or (n=2) then fibrek : = 1 else begin writeln ('Глубина рекурсии: ', n); delay(900) ; fibrek : = fibrek(n-1)+fibrek(n-2); end; begin write('Какое по счету число Фиббоначчи вывести? '); readln(n); writeln('Итеративно: ', fibit(n)); writeln('Рекурсивно: '); result : = fibrek(n); write (result); end.

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

Программа обработки рекуррентной последовательности program Sum; var n, k: integer; a, s: real; begin Программа обработки рекуррентной последовательности program Sum; var n, k: integer; a, s: real; begin writeln ('Введите целое число n'); readln ( n ); a: =1; s: =a; for k: =1 to n do begin a: =a/2; s: =s+a; end; writeln ('Сумма равна ', s: 5: 3); end.

Произвольное количество вложенных циклов • Разместив рекурсивные вызовы внутри цикла, получим вложенные циклы, где Произвольное количество вложенных циклов • Разместив рекурсивные вызовы внутри цикла, получим вложенные циклы, где уровень вложенности равен глубине рекурсии.

 • Сочетания из n чисел по 2 печатаются так: for i 1 : • Сочетания из n чисел по 2 печатаются так: for i 1 : = 1 to n do for i 2 : = i 1 + 1 to n do writeln(i 1, ' ', i 2); • Сочетания из n чисел по 3 так: for i 1 : = 1 to n do for i 2 : = i 1 + 1 to n do for i 3 : = i 2 + 1 to n do writeln(i 1, ' ', i 2, ' ', i 3); • Однако, если количество чисел в сочетании задается переменной, то придется прибегнуть к рекурсии (попробуйте самостоятельно!)