КАТЕГОРИИ: Архитектура-(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) |
Общие понятия. Рекурсивным называют метод, если он вызывает сам себя в качестве вспомогательного
Рекурсивным называют метод, если он вызывает сам себя в качестве вспомогательного. В основе рекурсивного метода лежит так называемое рекурсивное определение какого-либо понятия. Классическим примером рекурсивного метода является метод, вычисляющий факториал. Из курса математики известно, что 0!=1!=1, n!=1*2*3…*n. С другой стороны n!=(n -1)!* n. Таким образом, известны два частных случая параметра n, а именно n = 0 и n =1, при которых мы без каких-либо дополнительных вычислений можем определить значение факториала. Во всех остальных случаях, то есть для n >1, значение факториала может быть вычислено через значение факториала для параметра n -1. Таким образом, рекурсивный метод будет иметь вид:
long F(int n) { // Дошли до 0 или 1? if (n == 0 || n == 1) // Нерекурсивная ветвь return 1; else // Шаг рекурсии: повторный вызов // метода с другим параметром return n * F(n - 1); }
// Пример вызова рекурсивного метода long f = F(3); MessageBox.Show(f.ToString());
Рассмотрим работу описанного выше рекурсивного метода для n=3.
Рис. 14.1. Структура рекурсивных вызовов Первый вызов метода осуществляется из основной программы, в нашем случае командой f = F(3). Этап вхождения в рекурсию обозначим стрелками с подписью «шаг». Он продолжается до тех пор, пока значение переменной n не становится равной 1. После этого начинается выход из рекурсии (стрелки с подписью «возврат»). В результате вычислений получается, что F(3) = 3 * 2 * 1. Рассмотренный вид рекурсии называют прямой. Метод с прямой рекурсией обычно содержит следующую структуру:
if (<условие>) <оператор>; Else <вызов этого же метода с другими параметрами>;
В качестве <условия> обычно записываются некоторые граничные случаи параметров, передаваемых рекурсивному методу, при которых результат его работы заранее известен, поэтому далее следует простой оператор или блок, а в ветви else происходит рекурсивный вызов данного метода с другими параметрами. Что необходимо знать для реализации рекурсивного процесса? Со входом в рекурсию осуществляется вызов метода, а для выхода необходимо помнить точку возврата, т. е. то место программы откуда мы пришли и куда нам нужно будет возвратиться после завершения метода. Место хранения точек возврата называется стеком вызовов и для него выделяется определенная область оперативной памяти. В этом стеке запоминаются не только адреса точек возврата, но и копии значений всех параметров. По этим копиям восстанавливается при возврате вызывающий метод. При развертывании рекурсии за счет создания копий параметров возможно переполнение стека. Это является основным недостатком рекурсивного метода. С другой стороны, рекурсивные методы позволяют перейти к более компактной записи алгоритма. Следует понимать, что любой рекурсивный метод можно преобразовать в обычный метод с использованием циклов. И практически любой метод можно преобразовать в рекурсивный, если выявить рекуррентное соотношение между вычисляемыми в методе значениями. Рассмотрим пример кода для создания набора самоподобных структур. В нашем случае это будет набор увеличивающихся квадратов (рис. 15.2).
Рис. 15.2. Набор квадратов При проектировании данной программы были созданы два метода:
private void MyDraw(Graphics g, int N, int x, int y) { if (N == 0) return; else { // Отрисовка прямоугольника g.DrawRectangle(new Pen(Brushes.Blue, 2), 0, 0, x, y); // Увеличение x и y на 50 x += 50; y += 50; N--; // Рекурсивный вызов с новыми параметрами MyDraw(g, N, x, y); } }
private void Form1_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; // Первый вызов метода и вход в рекурсию MyDraw(g, 7, 50, 50); }
Координаты левого верхнего угла всех прямоугольников неизменны и находятся в точке (0, 0). Поэтому в параметрах метода MyDraw достаточно передавать x и y для правого нижнего угла. Также в параметрах передается N, значение которой определяет текущую вложенность рекурсии (сколько вызовов рекурсии еще будет).
Дата добавления: 2014-11-07; Просмотров: 697; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |