Your SlideShare is downloading. ×
  • Like
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Now you can save presentations on your phone or tablet

Available for both IPhone and Android

Text the download link to your phone

Standard text messaging rates apply

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

  • 121 views
Published

Училищен курс по програмиране на C# (2013/2014) …

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

Published in Education
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
121
On SlideShare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
3
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 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;
  • 20. Въпроси?
  • 21. Благодаря! • Валери Дачев – valery@david.bg – @vdachev – https://facebook.com/vdachev • ДАВИД академия – – – – acad@david.bg http://acad.david.bg/ @david_academy https://facebook.com/DavidAcademy