SlideShare a Scribd company logo
1 of 21
Курс по програмиране на C#
Занятие №5
Рекурсия

2013
Съдържание 1/2
• Рекурсия
– Какво е рекурсия?
– Как работи рекурсията?

• Видове рекурсия
– Единична и множествена рекурсия
– Пряка и косвена рекурсия
– Опашна рекурсия

• Използване на рекурсия
–
–
–
–

Приложение
Основни принципи
Предимства и недостатъци
Оптимизация
Съдържание 2/2
• Примери за рекурсия
–
–
–
–
–

Факториел
Числа на Фибоначи
Обръщане на масив
Двоично търсене в сортиран масив
Търсене на път в лабиринт
Рекурсия
• Какво е „рекурсия“?
– За определение на „рекурсия“ вж. „Какво е рекурсия“?
– Рекурсия в най-общ смисъл е представяне на един обект или
процес чрез самия него
– Рекурсия в математиката е изразяване на една функция чрез
самата нея
– Рекурсия в компютърното програмиране е решение, при което
едно функция използва сама себе си
Рекурсия
• Как работи извикването на функция?
– При извикване на функция, в стека се запазва информация за
локалните променливи и мястото на извикването и параметрите
– При връщане от извикване на функция, изпълнението продължава
от мястото на извикването, като локалните променливи и
параметрите се възстановяват

• Как работи рекурсията?
– Описаната схема на извикване на функции работи при
произволен брой вложени извиквания на различни функции
– В частност тези извиквания могат да бъдат рекурсивни
– Внимание: При прекалено много вложени извиквания, стекът може
да се препълни това да доведе до грешка и прекратяване
изпълнението на програмата
Рекурсия
1. Директор към секретарката:
– „Заминаваме на командировка в чужбина за седмица.“

2. Секретарката към мъжа си:
– „Заминавам с шефа на командировка в чужбина за седмица.“

3. Мъжът към любовницата си:
– „Жена ми заминава в командировка. Тази седмица сме заедно.“

4. Любовницата (учителка) към ученика си:
– „Болна съм, тази седмица. Няма да имаме уроци.“

5. Ученикът към дядо си:
– „Дядо, тази седмица идвам нагости, няма да имам уроци.“

6. Дядото (директорът) към секретарката си:
– „Внукът идва нагости тази седмица. Командировката се отлага.“

7. Go to 1.
Видове рекурсия
• Единична и множествена рекурсия
– Единична рекурсия е тази, при която има само едно рекурсивно
извикване
– Множествената рекурсия е тази, при която има повече от едно
рекурсивно извикване

• Пряка и косвена рекурсия
– Пряка рекурсия е тази, при която функцията извиква себе си
директно
– Косвена (непряка) рекурсия е тази, при която функцията извиква
себе си чрез извикване на друга функция
– Косвената рекурсия се нарича още споделена рекурсия, тъй като
всички функции участващи в нея се извикват рекурсивно, макар и
косвено
Видове рекурсия
• Опашна рекурсия
– Опашно извикване е извикване на функция като последно действие
в друга функция
– Извикваната функция може да връща резултат, който да се върне
на извикващата функция
– Ако в резултат на опашното извикване в дадена функция същата
функция бъде извикана отново, то говорим за опашна рекурсия
– С други думи, опашна рекурсия е тази, при която рекурсивното
извикване се осъществява в „опашката“ на функцията
– Опашната рекурсия винаги може да бъде сведена до итерация
(оптимизация на опашна рекурсия)
Използване на рекурсия
• Приложение
– Решаване на математически задачи, решенията на които са
зададени с рекурсивна връзка
– Разбиване на решението на по-малки сходни решения и
обединяване на техните резултати („разделяй и владей“) –
динамично програмиране/оптимиране.
– Рекурсия + таблици за търсене = мемоизация

• Основни принципи
– Всяко рекурсивно извикване трябва да опростява решението
– Рекурсията трябва да съдържа условие за край (т.нар. дъно на
рекурсията)
Използване на рекурсия
• Предимства
– Опростява решението на множество задачите чрез разбиването
им на малки прости подзадачи

• Недостатъци
– Значително по-бавна работа, поради засилено използване на
стека
– Прекомерно използване на стек

• Оптимизация
– Свеждане на рекурсията до итерация, когато това е възможно
• Използване на собствени стекови структури за симулиране на рекурсия

– Използване на мемоизация, когато рекурсивните извиквания дават
еднозначен резултат при едни и същи аргументи
Примери за рекурсия – факториел
• Какво е факториел?
– Класическа дефиниция
n! = 1. 2 . 3 . … . (n-1) . n , n ∈ ℕ
0! = 1 (граничен случай)

– Рекурсивна дефиниция
n! = n . (n-1)! , n ∈ ℕ
0! = 1 (дъно на рекурсията)

• Факториелът е бързо растяща функция
• За големи стойности, използвайте
BigInteger вместо int
Примери за рекурсия – факториел
• Итеративно намиране на
факториел
– Итеративна дефиниция:
n! = 1. 2 . 3 . … . (n-1) . n , n ∈ ℕ
0! = 1 (граничен случай)

// факториел - итеративно
int GetFactorialIter(int n)
{
int result = 1;
// n! = 1.2.3. … .n
for (int i = 1; i <= n; i++)
result *= i;
return result;
}
Примери за рекурсия – факториел
• Рекурсивно намиране на
факториел
– Рекурсивна дефиниция:
n! = n . (n-1)! , n ∈ ℕ
0! = 1 (дъно на рекурсията)

// факториел – рекурсивно
int GetFactorialRec(int n)
{
// 0! = 1
if (n <= 0)
return 1;
// n! = n . (n-1)!
return n * GetFactorialRec(n-1);
}
Примери за рекурсия – числа на Фибоначи
• Кои са числата на Фибоначи?
– Рекурсивна дефиниция:
Fn = Fn-1 + Fn-2
F0 = 1, F1 = 1

// числа на Фибоначи – рекурсивно
int GetFibonacciNumbersRec(int n)
{
// F0 = 1, F1 = 1
if (n <= 1) return 1;
// Fn = Fn-1 + Fn-2
return GetFibonacciNumbersRec(n - 1)
+ GetFibonacciNumbersRec(n - 2);
}
Примери за рекурсия – обръщане на масив
• Рекурсивно обръщане на
масив
– Ако краищата на масива са се
разминали, се връщаме
обратно
– Разменяме крайните елементи
на масива
– Обръщаме подмасива от
елемент 1 до елемент n-2

// обръщане на масив – рекурсивно
void ReverseArrayRec(int[] a,
int start, int end)
{
// краищата на масива са се разминали
if (end <= start)
return;
// разменяме крайните елементи
int t = a[end];
a[end] = a[start];
a[start] = t;
// обръщаме подмасива
ReverseArrayRec(a, start + 1, end – 1);
}
Примери за рекурсия – дв. търсене в сорт. масив
• Двоично търсене в сортиран масив
– Ако краищата на масива са се
разминали, се връщаме неуспешно
– Взимаме средния елемент и
стойността му наричаме „ключ“
– Ако ключът:
• е по-малък от елемента, който търсим,
търсим в дясно стоящия подмасив
• е по-голям от елемента, който търсим,
търсим в ляво стоящия подмасив
• съвпада с елемента, който търсим,
връщаме индекса му
Примери за рекурсия – търсене на път в лабиринт
• Търсене на път в лабиринт
– Рекурсивното търсене на път в лабиринт се основава на принципа
„проба-грешка“
– На всяка стъпка:
1. Проверяваме дали сме стигнали. Ако да, се връщаме успешно.
2. Маркираме настоящата позиция като настъпана
3. Стъпваме във всяка една посока, докато не се
изчерпат и/или не сме намерили пътя
Задачи за упражнение
• Създайте програма със следните функции:
– CreateMatrix, която създава масив от елементи от
тип ConsoleColor попълнен произволно с бяло
(White) и черно (Black).
– ShowMatrix, която визуализира създадения масив по
подходящ начин
– FillMatrix, която започва да запълва бял регион с червено
използвайки рекурсивния flood fill алгоритъм, започвайки от
произволна бяла позиция.
– Нека във всяко рекурсивно извикване на FillMatrix се извиква и
ShowMatrix, така че визуализираният масив да се опреснява.
Задачи за упражнение
• Направете рекурсивна функция, която да намира и
изпечатва наименованията на всички файлове и техните
големини намиращи се в папка с подадено име и на
подадена дълбочина в нейните подпапки.
– За да вземете списък с наименованията на папките в дадена
папка, използвайте
string[] folderNames = Directory.GetDirectories(path);

– За да вземете списък с наименованията на файловете в дадена
папка, използвайте:
string[] fileNames = Directory.GetFiles(path);

– За да вземете големината на файл, използвайте код като следния:
long length = new FileInfo(fileName).Length;
Въпроси?
Благодаря!
• Валери Дачев
– valery@david.bg
– @vdachev
– https://facebook.com/vdachev

• ДАВИД академия
–
–
–
–

acad@david.bg
http://acad.david.bg/
@david_academy
https://facebook.com/DavidAcademy

More Related Content

More from DAVID Academy

Курс по уеб програмиране (2014), занятие №4 - JavaScript (част 2/2)
Курс по уеб програмиране (2014), занятие №4 - JavaScript (част 2/2)Курс по уеб програмиране (2014), занятие №4 - JavaScript (част 2/2)
Курс по уеб програмиране (2014), занятие №4 - JavaScript (част 2/2)DAVID Academy
 
Курс по уеб програмиране (2014), занятие №3 - JavaScript (част 1/2)
Курс по уеб програмиране (2014), занятие №3 - JavaScript (част 1/2)Курс по уеб програмиране (2014), занятие №3 - JavaScript (част 1/2)
Курс по уеб програмиране (2014), занятие №3 - JavaScript (част 1/2)DAVID Academy
 
Училищен курс по програмиране на C# (2013/2014), занятие №13
Училищен курс по програмиране на C# (2013/2014), занятие №13Училищен курс по програмиране на C# (2013/2014), занятие №13
Училищен курс по програмиране на C# (2013/2014), занятие №13DAVID Academy
 
Курс по уеб програмиране (2014), занятие №2 - CSS
Курс по уеб програмиране (2014), занятие №2 - CSSКурс по уеб програмиране (2014), занятие №2 - CSS
Курс по уеб програмиране (2014), занятие №2 - CSSDAVID Academy
 
Училищен курс по програмиране на C# (2013/2014), занятие №12
Училищен курс по програмиране на C# (2013/2014), занятие №12Училищен курс по програмиране на C# (2013/2014), занятие №12
Училищен курс по програмиране на C# (2013/2014), занятие №12DAVID Academy
 
Курс по уеб програмиране (2014), занятие №1 - HTML
Курс по уеб програмиране (2014), занятие №1 - HTMLКурс по уеб програмиране (2014), занятие №1 - HTML
Курс по уеб програмиране (2014), занятие №1 - HTMLDAVID Academy
 
Училищен курс по програмиране на C# (2013/2014), занятие №11
Училищен курс по програмиране на C# (2013/2014), занятие №11Училищен курс по програмиране на C# (2013/2014), занятие №11
Училищен курс по програмиране на C# (2013/2014), занятие №11DAVID Academy
 
Училищен курс по програмиране на C# (2013/2014), занятие №10
Училищен курс по програмиране на C# (2013/2014), занятие №10Училищен курс по програмиране на C# (2013/2014), занятие №10
Училищен курс по програмиране на C# (2013/2014), занятие №10DAVID Academy
 
Училищен курс по програмиране на C# (2013/2014), занятие №9
Училищен курс по програмиране на C# (2013/2014), занятие №9Училищен курс по програмиране на C# (2013/2014), занятие №9
Училищен курс по програмиране на C# (2013/2014), занятие №9DAVID Academy
 
Училищен курс по програмиране на C# (2013/2014), занятие №8
Училищен курс по програмиране на C# (2013/2014), занятие №8Училищен курс по програмиране на C# (2013/2014), занятие №8
Училищен курс по програмиране на C# (2013/2014), занятие №8DAVID Academy
 
Училищен курс по програмиране на C# (2013/2014), занятие №7
Училищен курс по програмиране на C# (2013/2014), занятие №7Училищен курс по програмиране на C# (2013/2014), занятие №7
Училищен курс по програмиране на C# (2013/2014), занятие №7DAVID Academy
 
Училищен курс по програмиране на C# (2013/2014) - Помагало
Училищен курс по програмиране на C# (2013/2014) - ПомагалоУчилищен курс по програмиране на C# (2013/2014) - Помагало
Училищен курс по програмиране на C# (2013/2014) - ПомагалоDAVID Academy
 
Училищен курс по програмиране на C# (2013/2014) - Упражнения
Училищен курс по програмиране на C# (2013/2014) - УпражненияУчилищен курс по програмиране на C# (2013/2014) - Упражнения
Училищен курс по програмиране на C# (2013/2014) - УпражненияDAVID Academy
 
Курс по информационни технологии (2013) - 5. HTTP & Web Services
Курс по информационни технологии (2013) - 5. HTTP & Web ServicesКурс по информационни технологии (2013) - 5. HTTP & Web Services
Курс по информационни технологии (2013) - 5. HTTP & Web ServicesDAVID Academy
 
Курс по информационни технологии (2013) - 4. XML, XSD, XML в .NET Framework
Курс по информационни технологии (2013) - 4. XML, XSD, XML в .NET FrameworkКурс по информационни технологии (2013) - 4. XML, XSD, XML в .NET Framework
Курс по информационни технологии (2013) - 4. XML, XSD, XML в .NET FrameworkDAVID Academy
 
Курс по информационни технологии (2013) - 3. ADO.NET, LINQ to SQL
Курс по информационни технологии (2013) - 3. ADO.NET, LINQ to SQLКурс по информационни технологии (2013) - 3. ADO.NET, LINQ to SQL
Курс по информационни технологии (2013) - 3. ADO.NET, LINQ to SQLDAVID Academy
 
Курс по информационни технологии (2013) - 2. Бази данни. Системи за управлени...
Курс по информационни технологии (2013) - 2. Бази данни. Системи за управлени...Курс по информационни технологии (2013) - 2. Бази данни. Системи за управлени...
Курс по информационни технологии (2013) - 2. Бази данни. Системи за управлени...DAVID Academy
 
Курс по информационни технологии (2013) - 1. Desktop приложения. Windows Form...
Курс по информационни технологии (2013) - 1. Desktop приложения. Windows Form...Курс по информационни технологии (2013) - 1. Desktop приложения. Windows Form...
Курс по информационни технологии (2013) - 1. Desktop приложения. Windows Form...DAVID Academy
 
Курс по информационни технологии (2013) - 0. Представяне
Курс по информационни технологии (2013) - 0. ПредставянеКурс по информационни технологии (2013) - 0. Представяне
Курс по информационни технологии (2013) - 0. ПредставянеDAVID Academy
 
Курс по информационни технологии (2013) - Помагало
Курс по информационни технологии (2013) - ПомагалоКурс по информационни технологии (2013) - Помагало
Курс по информационни технологии (2013) - ПомагалоDAVID Academy
 

More from DAVID Academy (20)

Курс по уеб програмиране (2014), занятие №4 - JavaScript (част 2/2)
Курс по уеб програмиране (2014), занятие №4 - JavaScript (част 2/2)Курс по уеб програмиране (2014), занятие №4 - JavaScript (част 2/2)
Курс по уеб програмиране (2014), занятие №4 - JavaScript (част 2/2)
 
Курс по уеб програмиране (2014), занятие №3 - JavaScript (част 1/2)
Курс по уеб програмиране (2014), занятие №3 - JavaScript (част 1/2)Курс по уеб програмиране (2014), занятие №3 - JavaScript (част 1/2)
Курс по уеб програмиране (2014), занятие №3 - JavaScript (част 1/2)
 
Училищен курс по програмиране на C# (2013/2014), занятие №13
Училищен курс по програмиране на C# (2013/2014), занятие №13Училищен курс по програмиране на C# (2013/2014), занятие №13
Училищен курс по програмиране на C# (2013/2014), занятие №13
 
Курс по уеб програмиране (2014), занятие №2 - CSS
Курс по уеб програмиране (2014), занятие №2 - CSSКурс по уеб програмиране (2014), занятие №2 - CSS
Курс по уеб програмиране (2014), занятие №2 - CSS
 
Училищен курс по програмиране на C# (2013/2014), занятие №12
Училищен курс по програмиране на C# (2013/2014), занятие №12Училищен курс по програмиране на C# (2013/2014), занятие №12
Училищен курс по програмиране на C# (2013/2014), занятие №12
 
Курс по уеб програмиране (2014), занятие №1 - HTML
Курс по уеб програмиране (2014), занятие №1 - HTMLКурс по уеб програмиране (2014), занятие №1 - HTML
Курс по уеб програмиране (2014), занятие №1 - HTML
 
Училищен курс по програмиране на C# (2013/2014), занятие №11
Училищен курс по програмиране на C# (2013/2014), занятие №11Училищен курс по програмиране на C# (2013/2014), занятие №11
Училищен курс по програмиране на C# (2013/2014), занятие №11
 
Училищен курс по програмиране на C# (2013/2014), занятие №10
Училищен курс по програмиране на C# (2013/2014), занятие №10Училищен курс по програмиране на C# (2013/2014), занятие №10
Училищен курс по програмиране на C# (2013/2014), занятие №10
 
Училищен курс по програмиране на C# (2013/2014), занятие №9
Училищен курс по програмиране на C# (2013/2014), занятие №9Училищен курс по програмиране на C# (2013/2014), занятие №9
Училищен курс по програмиране на C# (2013/2014), занятие №9
 
Училищен курс по програмиране на C# (2013/2014), занятие №8
Училищен курс по програмиране на C# (2013/2014), занятие №8Училищен курс по програмиране на C# (2013/2014), занятие №8
Училищен курс по програмиране на C# (2013/2014), занятие №8
 
Училищен курс по програмиране на C# (2013/2014), занятие №7
Училищен курс по програмиране на C# (2013/2014), занятие №7Училищен курс по програмиране на C# (2013/2014), занятие №7
Училищен курс по програмиране на C# (2013/2014), занятие №7
 
Училищен курс по програмиране на C# (2013/2014) - Помагало
Училищен курс по програмиране на C# (2013/2014) - ПомагалоУчилищен курс по програмиране на C# (2013/2014) - Помагало
Училищен курс по програмиране на C# (2013/2014) - Помагало
 
Училищен курс по програмиране на C# (2013/2014) - Упражнения
Училищен курс по програмиране на C# (2013/2014) - УпражненияУчилищен курс по програмиране на C# (2013/2014) - Упражнения
Училищен курс по програмиране на C# (2013/2014) - Упражнения
 
Курс по информационни технологии (2013) - 5. HTTP & Web Services
Курс по информационни технологии (2013) - 5. HTTP & Web ServicesКурс по информационни технологии (2013) - 5. HTTP & Web Services
Курс по информационни технологии (2013) - 5. HTTP & Web Services
 
Курс по информационни технологии (2013) - 4. XML, XSD, XML в .NET Framework
Курс по информационни технологии (2013) - 4. XML, XSD, XML в .NET FrameworkКурс по информационни технологии (2013) - 4. XML, XSD, XML в .NET Framework
Курс по информационни технологии (2013) - 4. XML, XSD, XML в .NET Framework
 
Курс по информационни технологии (2013) - 3. ADO.NET, LINQ to SQL
Курс по информационни технологии (2013) - 3. ADO.NET, LINQ to SQLКурс по информационни технологии (2013) - 3. ADO.NET, LINQ to SQL
Курс по информационни технологии (2013) - 3. ADO.NET, LINQ to SQL
 
Курс по информационни технологии (2013) - 2. Бази данни. Системи за управлени...
Курс по информационни технологии (2013) - 2. Бази данни. Системи за управлени...Курс по информационни технологии (2013) - 2. Бази данни. Системи за управлени...
Курс по информационни технологии (2013) - 2. Бази данни. Системи за управлени...
 
Курс по информационни технологии (2013) - 1. Desktop приложения. Windows Form...
Курс по информационни технологии (2013) - 1. Desktop приложения. Windows Form...Курс по информационни технологии (2013) - 1. Desktop приложения. Windows Form...
Курс по информационни технологии (2013) - 1. Desktop приложения. Windows Form...
 
Курс по информационни технологии (2013) - 0. Представяне
Курс по информационни технологии (2013) - 0. ПредставянеКурс по информационни технологии (2013) - 0. Представяне
Курс по информационни технологии (2013) - 0. Представяне
 
Курс по информационни технологии (2013) - Помагало
Курс по информационни технологии (2013) - ПомагалоКурс по информационни технологии (2013) - Помагало
Курс по информационни технологии (2013) - Помагало
 

Училищен курс по програмиране на C# (2013/2014), занятие №5

  • 1. Курс по програмиране на C# Занятие №5 Рекурсия 2013
  • 2. Съдържание 1/2 • Рекурсия – Какво е рекурсия? – Как работи рекурсията? • Видове рекурсия – Единична и множествена рекурсия – Пряка и косвена рекурсия – Опашна рекурсия • Използване на рекурсия – – – – Приложение Основни принципи Предимства и недостатъци Оптимизация
  • 3. Съдържание 2/2 • Примери за рекурсия – – – – – Факториел Числа на Фибоначи Обръщане на масив Двоично търсене в сортиран масив Търсене на път в лабиринт
  • 4. Рекурсия • Какво е „рекурсия“? – За определение на „рекурсия“ вж. „Какво е рекурсия“? – Рекурсия в най-общ смисъл е представяне на един обект или процес чрез самия него – Рекурсия в математиката е изразяване на една функция чрез самата нея – Рекурсия в компютърното програмиране е решение, при което едно функция използва сама себе си
  • 5. Рекурсия • Как работи извикването на функция? – При извикване на функция, в стека се запазва информация за локалните променливи и мястото на извикването и параметрите – При връщане от извикване на функция, изпълнението продължава от мястото на извикването, като локалните променливи и параметрите се възстановяват • Как работи рекурсията? – Описаната схема на извикване на функции работи при произволен брой вложени извиквания на различни функции – В частност тези извиквания могат да бъдат рекурсивни – Внимание: При прекалено много вложени извиквания, стекът може да се препълни това да доведе до грешка и прекратяване изпълнението на програмата
  • 6. Рекурсия 1. Директор към секретарката: – „Заминаваме на командировка в чужбина за седмица.“ 2. Секретарката към мъжа си: – „Заминавам с шефа на командировка в чужбина за седмица.“ 3. Мъжът към любовницата си: – „Жена ми заминава в командировка. Тази седмица сме заедно.“ 4. Любовницата (учителка) към ученика си: – „Болна съм, тази седмица. Няма да имаме уроци.“ 5. Ученикът към дядо си: – „Дядо, тази седмица идвам нагости, няма да имам уроци.“ 6. Дядото (директорът) към секретарката си: – „Внукът идва нагости тази седмица. Командировката се отлага.“ 7. Go to 1.
  • 7. Видове рекурсия • Единична и множествена рекурсия – Единична рекурсия е тази, при която има само едно рекурсивно извикване – Множествената рекурсия е тази, при която има повече от едно рекурсивно извикване • Пряка и косвена рекурсия – Пряка рекурсия е тази, при която функцията извиква себе си директно – Косвена (непряка) рекурсия е тази, при която функцията извиква себе си чрез извикване на друга функция – Косвената рекурсия се нарича още споделена рекурсия, тъй като всички функции участващи в нея се извикват рекурсивно, макар и косвено
  • 8. Видове рекурсия • Опашна рекурсия – Опашно извикване е извикване на функция като последно действие в друга функция – Извикваната функция може да връща резултат, който да се върне на извикващата функция – Ако в резултат на опашното извикване в дадена функция същата функция бъде извикана отново, то говорим за опашна рекурсия – С други думи, опашна рекурсия е тази, при която рекурсивното извикване се осъществява в „опашката“ на функцията – Опашната рекурсия винаги може да бъде сведена до итерация (оптимизация на опашна рекурсия)
  • 9. Използване на рекурсия • Приложение – Решаване на математически задачи, решенията на които са зададени с рекурсивна връзка – Разбиване на решението на по-малки сходни решения и обединяване на техните резултати („разделяй и владей“) – динамично програмиране/оптимиране. – Рекурсия + таблици за търсене = мемоизация • Основни принципи – Всяко рекурсивно извикване трябва да опростява решението – Рекурсията трябва да съдържа условие за край (т.нар. дъно на рекурсията)
  • 10. Използване на рекурсия • Предимства – Опростява решението на множество задачите чрез разбиването им на малки прости подзадачи • Недостатъци – Значително по-бавна работа, поради засилено използване на стека – Прекомерно използване на стек • Оптимизация – Свеждане на рекурсията до итерация, когато това е възможно • Използване на собствени стекови структури за симулиране на рекурсия – Използване на мемоизация, когато рекурсивните извиквания дават еднозначен резултат при едни и същи аргументи
  • 11. Примери за рекурсия – факториел • Какво е факториел? – Класическа дефиниция n! = 1. 2 . 3 . … . (n-1) . n , n ∈ ℕ 0! = 1 (граничен случай) – Рекурсивна дефиниция n! = n . (n-1)! , n ∈ ℕ 0! = 1 (дъно на рекурсията) • Факториелът е бързо растяща функция • За големи стойности, използвайте BigInteger вместо int
  • 12. Примери за рекурсия – факториел • Итеративно намиране на факториел – Итеративна дефиниция: n! = 1. 2 . 3 . … . (n-1) . n , n ∈ ℕ 0! = 1 (граничен случай) // факториел - итеративно int GetFactorialIter(int n) { int result = 1; // n! = 1.2.3. … .n for (int i = 1; i <= n; i++) result *= i; return result; }
  • 13. Примери за рекурсия – факториел • Рекурсивно намиране на факториел – Рекурсивна дефиниция: n! = n . (n-1)! , n ∈ ℕ 0! = 1 (дъно на рекурсията) // факториел – рекурсивно int GetFactorialRec(int n) { // 0! = 1 if (n <= 0) return 1; // n! = n . (n-1)! return n * GetFactorialRec(n-1); }
  • 14. Примери за рекурсия – числа на Фибоначи • Кои са числата на Фибоначи? – Рекурсивна дефиниция: Fn = Fn-1 + Fn-2 F0 = 1, F1 = 1 // числа на Фибоначи – рекурсивно int GetFibonacciNumbersRec(int n) { // F0 = 1, F1 = 1 if (n <= 1) return 1; // Fn = Fn-1 + Fn-2 return GetFibonacciNumbersRec(n - 1) + GetFibonacciNumbersRec(n - 2); }
  • 15. Примери за рекурсия – обръщане на масив • Рекурсивно обръщане на масив – Ако краищата на масива са се разминали, се връщаме обратно – Разменяме крайните елементи на масива – Обръщаме подмасива от елемент 1 до елемент n-2 // обръщане на масив – рекурсивно void ReverseArrayRec(int[] a, int start, int end) { // краищата на масива са се разминали if (end <= start) return; // разменяме крайните елементи int t = a[end]; a[end] = a[start]; a[start] = t; // обръщаме подмасива ReverseArrayRec(a, start + 1, end – 1); }
  • 16. Примери за рекурсия – дв. търсене в сорт. масив • Двоично търсене в сортиран масив – Ако краищата на масива са се разминали, се връщаме неуспешно – Взимаме средния елемент и стойността му наричаме „ключ“ – Ако ключът: • е по-малък от елемента, който търсим, търсим в дясно стоящия подмасив • е по-голям от елемента, който търсим, търсим в ляво стоящия подмасив • съвпада с елемента, който търсим, връщаме индекса му
  • 17. Примери за рекурсия – търсене на път в лабиринт • Търсене на път в лабиринт – Рекурсивното търсене на път в лабиринт се основава на принципа „проба-грешка“ – На всяка стъпка: 1. Проверяваме дали сме стигнали. Ако да, се връщаме успешно. 2. Маркираме настоящата позиция като настъпана 3. Стъпваме във всяка една посока, докато не се изчерпат и/или не сме намерили пътя
  • 18. Задачи за упражнение • Създайте програма със следните функции: – CreateMatrix, която създава масив от елементи от тип ConsoleColor попълнен произволно с бяло (White) и черно (Black). – ShowMatrix, която визуализира създадения масив по подходящ начин – FillMatrix, която започва да запълва бял регион с червено използвайки рекурсивния flood fill алгоритъм, започвайки от произволна бяла позиция. – Нека във всяко рекурсивно извикване на FillMatrix се извиква и ShowMatrix, така че визуализираният масив да се опреснява.
  • 19. Задачи за упражнение • Направете рекурсивна функция, която да намира и изпечатва наименованията на всички файлове и техните големини намиращи се в папка с подадено име и на подадена дълбочина в нейните подпапки. – За да вземете списък с наименованията на папките в дадена папка, използвайте string[] folderNames = Directory.GetDirectories(path); – За да вземете списък с наименованията на файловете в дадена папка, използвайте: string[] fileNames = Directory.GetFiles(path); – За да вземете големината на файл, използвайте код като следния: long length = new FileInfo(fileName).Length;
  • 21. Благодаря! • Валери Дачев – valery@david.bg – @vdachev – https://facebook.com/vdachev • ДАВИД академия – – – – acad@david.bg http://acad.david.bg/ @david_academy https://facebook.com/DavidAcademy