რეკურსიული პროგრამირება Recursio ლათინურად “დაბრუნება”-ს ნიშნავს რეკურსია წარმოადგენს მეთოდს, რომელსაც ზოგადი ამოცანა დაჰყავს უფრო მცირე ზომის, მარტივი ამოცანების ამოხსნაზე რეკურსიული ალგორითმი მუშაობის პროცესში საკუთარ თავს მიმართავს. რეკურსიის არსი იმაში მდგომარეობს, რომ ფუნქციის მიერ საკუთარი თავის ყოველი გამოძახებისას მეხსიერებაში იქმნება ფუნქციის ახალი ასლი შესაბამისი ლოკალური ცვლადებით, ხოლო მუშაობის დამთავრებისთანავე ეს მეხსიერება თავისუფლდება და შედეგები გადაეცემა გამოძახების წერტილს.
რეკურსია შეიძლება იყოს: პირდაპირი, როცა ფუნქცია იძახებს თავის თავს. ირიბი, როცა A ფუნქცია იძახებს B-ს, ხოლო B ფუნქცია A-ს.
რეკურსიის ლიტერატურულ მაგალითებად შეიძლება ჩაითვალოს “რწყილი და ჭიანჭველა”, “თხა და ვენახი”... ორ სარკეს შორის მოთავსებული საგანი წარმოშობს რეკურსიულ გამოსახულებათა უსასრულო როდენობას.
ფაქტორიალის გამოთვლა რეკურსიულად N! = 1, როცა N = 1 N * (N – 1)!, როცა N > 1 რეკურსიის დროს მნიშვნელოვანია ქვეპროგრამიდან (ფუქციიდან) გამოსვლის მომენტის მკაფიო განსაზღვრა, რათა ალგორითმი სასრული იყოს. int factorial( int a) { if (a == 1) return 1; else { a = a * factorial(a-1); return a; }
ფუნქციის პირველი გამოძახება ძირითადი პროგრამიდან უნდა მოხდეს. მაგ ფუნქციის პირველი გამოძახება ძირითადი პროგრამიდან უნდა მოხდეს. მაგ., α= fact(5) გამოვთვალოთ 5! 1 გამოძახება (n=5) Function fact { fact= 5 * fact(4); } 2 გამოძახება (n=4) fact(5) = 120 Function fact { fact= 4* fact(3); } 5 *24 3 გამოძახება (n=3) α= 120 Function fact { fact= 3* fact(2); } 4 *6 4 გამოძახება (n=2) Function fact { fact= 2* fact(1); } 5 გამოძახება (n=1) 3 *2 Function fact { fact= 1; } 2 *1
მაგალითი: ნატურალური რიცხვის გადაყვანა თვლის ათობითი სისტემიდან ორობითში. 39 38 19 18 9 8 4 2 1 3910 = 1001112 rec(int n) { if (n >1) rec(n/2); cout<<n%2; }
int rec(int n) { cout<<n%2; } { cout<<n%2; } { if (n>1) rec(n/2); cout<<n%2; } 2 გამოძახება (n = 19) int rec(int n) { if (n>1) rec(n/2); cout<<n%2; } 3 გამოძახება (n = 9) int rec(int n) { if (n>1) rec(n/2); cout<<n%2; } 4 გამოძახება (n = 4) int rec(int n) { if (n>1) rec(n/2); cout<<n%2; } 5 გამოძახება (n = 2) int rec(int n) { if (n>1) rec(n/2); cout<<n%2; } 6 გამოძახება (n = 1) int rec(int n) { cout<<n%2; }
ფიბონაჩის მიმდევრობა ვიპოვოთ ფიბონაჩის მიმდევრობის საწყისი N წევრი. ცნობილია, რომ ამ მიმდევრობის პირეველი ორი წევრი 1-ის ტოლია, ხოლო ყოველი მომდევნო წევრი წინა ორი წევრის ჯამის ტოლია (1, 1, 2, 3, 5, 8, 13, 21, …). ამოცანის რეკურსიული აღწერა: Ф(n) = 1, თუ n = 1 ან n = 2; Ф(n – 1) + Ф(n – 2), როცა n > 2
ფიბონაჩის მიმდევრობა ეს პროგრამა ნათლად ამჟღავნებს რეკურსიის ნაკლოვან მხარეს. K>70 მნიშვნელობებისათვის პროგრამა ძალზე დიდ დროს ანდომებს. საქმე იმაშია, რომ FIB[70]-ის გამოთვლისთვის რეკურსიულმა ფუნქციამ უნდა გამოთვალოს FIB[69] და FIB[68]. მიუხედავად იმისა, რომ FIB[68] ფუნქციას უკვე გამოთვლილი ჰქონდა FIB[69]-ის გამოთვლის დროს, ის ამ მნიშვნელობას თავიდან ითვლის და ასე იქცევა მიმდევრობის ყველა სხვა წევრის მიმართაც. სწორედ ეს გახლავთ რეკურსიის ნელი მუშაობის მიზეზი – ის უამრავჯერ ითვლის ფუნქციის მნიშვნელობას ერთი და იგივე არგუმენტისათვის. მართალია, მასივის შემოღება და მიღებული შედეგების მასში შენახვა მკვეთრად გააუმჯობესებს რეკურსიის მუშაობის სიჩქარესაც. ამ შემთხვევაში რეკურსიულ ვარიანტზე გაცილებით ეფექტურია იტერაციული ვარიანტი. #include<iostream> using namespace std; int k,x; int fibon(int n) { if(n<=2) return 1; return fibon(n-1)+fibon(n-2); } main (){ cin>>k; x=fibon(k); cout<<x<<endl;
რეკურსიის ხე ფიბონაჩის მიმდევრობისათვის 1 - 39088169 2 - 63245986 3 - 39088169 4 - 24157817 5 - 14930352 6 - 9227465 7 - 5702887 8 - 3524578 9 - 2178309 10 - 1346269 11 - 832040 12 - 514229 13 - 317811 14 - 196418 15 - 121393 16 - 75025 17 - 46368 18 - 28657 19 - 17711 20 - 10946 21 - 6765 22 - 4181 23 - 2584 24 - 1597 25 - 987 26 - 610 27 - 377 28 - 233 29 - 144 30 - 89 31 - 55 32 - 34 33 - 21 34 - 13 35 - 8 36 - 5 37 - 3 38 - 2 39 - 1 40 - 1 ცხრილებში ნაჩვენებია გამოძახებათა რაოდენობა n=40-სათვის
პროგრამა, რომელიც ახდენს მთელი რიცხვის ჩანაწერის შებრუნებას #include <iostream> using namespace std; int n; int revers(int n1) { cout<<n1%10; if (n1/10!=0) revers(n1/10); return 0; } int main(){ cin>>n; revers(n);
ორობითი ძებნა ორობითი ძებნა პოულობს საძებნი ელემენტის მდებარეობას (ინდექსს) დალაგებულ მასივში (ან სიაში) ყოველ ბიჯზე საძებნი არის ორჯერ შემცირებით. ორობითი ძებნა ახორციელებს O(log N) შედარებას. მაგალითი: მოვძებნოთ მასივში რიცხვი 43. index 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 value -7 -2 21 23 31 33 37 43 51 55 78 86 94 114 min mid max
ორობითი ძებნის კოდი #include <iostream> using namespace std; int bsearch(int L[],int x, int first, int last) { if (last >= first) { int middle = (first + last) / 2; if (x == L[middle]) return middle; else if (x < L[middle]) return bsearch(L, x, first, middle-1); else return bsearch(L, x, middle+1, last); } return -(first + 1); int main(){ int myList[] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19}; int size, myfirst = 0, findthis; int n = myList[size]; int mylast = n - 1; cin >> findthis; int result = binarySearch(myList, findthis, myfirst, mylast);