Технологии Программирования. 5 лекция
.pdfПоследовательность
вызовов процедуры tn при n=3 иллюстрируется древовидной структурой
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
|
|
|
|
ханойские башни |
*/ |
|
|
|
|||||||||||||||||||||||||||||||||||||
|
|
|
|
#include |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||
|
|
|
main() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||
|
|
|
{ void tn(int, int, int, int); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||||||||||
|
|
|
int n; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||
|
|
|
scanf(" %d",&n); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||||||||||
|
|
|
tn(n,1,2,3); |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void tn(int n, int i, int j, int w)
{ if (n>1) { tn (n-1,i,w,j); tn (1,i,j,w); tn (n-1,w,j,i); } else printf(" \n %d -> %d",i,j);
return ; }
Рекурсивное построение кривых Гильберта
(Hilbert curves)
это самоподобные (self-similar) кривые, которые обычно определяются при помощи рекурсии.
Кривые Серпинского
7. Когда нужно использовать рекурсию?
•методы устранения рекурсии из любого алгоритма.
Если рекурсивный алгоритм можно реализовать с помощью рекуррентных соотношений, то это нужно делать и избавляться от рекурсий.
•Функции, вычисляющиеп без применения рекурсии:
Пример 1 п!= ∏i i=1
Пример 2
n
xn =∏x
i=1
Пример 3: наибольший общий делитель – Д/З
Пример4: числа Фибоначчи (без рекурсии) вариант 1
…
int fib0,fib1,fibk,k,n;
…
fib0=0; fib1=1;
//восстановить все числа n> 1 k=1; while (k<n)
{fibk = fib0+fib1;k++; printf(“\n %d %d”, k, fibk);
fib0=fib1; fib1=fibk;
}
….
Д/З «дописать» программу с использованием массива
8.Опасности рекурсии
Рекурсия может служить мощным методом разбиения
больших задач на части, но она таит в себе несколько
опасностей.
1) Бесконечная рекурсия
Если неправильно построить алгоритм, то функция может пропустить условие остановки рекурсии и выполняться бесконечно.
Например
int Bad_factorial (int n)
{ return (n* Bad_factorial (n - 1));
}