Студопедия

КАТЕГОРИИ:


Архитектура-(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; Просмотров: 662; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




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