Η δομή δεδομένων χρησιμοποιείται για την εκτέλεση αναδρομής. Αναδρομικό TCI από το Yandex. Πρακτικές Εφαρμογές Αναδρομής

Η αναδρομή είναι η ιδιότητα ενός αντικειμένου να μιμείται τον εαυτό του. Ένα αντικείμενο είναι αναδρομικό αν τα μέρη του φαίνονται ίδια με ολόκληρο το αντικείμενο. Η αναδρομή χρησιμοποιείται ευρέως στα μαθηματικά και στον προγραμματισμό:

  • ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ:
    • ένα γράφημα (ιδίως τα δέντρα και οι λίστες) μπορεί να θεωρηθεί ως μια συλλογή ενός μεμονωμένου κόμβου και ενός υπογράφου (μικρότερο γράφημα).
    • η συμβολοσειρά αποτελείται από τον πρώτο χαρακτήρα και μια δευτερεύουσα συμβολοσειρά (μικρότερη συμβολοσειρά).
  • σχέδια σχεδίασης, π.χ. Ένα αντικείμενο διακοσμητή μπορεί να περιλαμβάνει άλλα αντικείμενα που είναι επίσης διακοσμητές. Ο McColm Smith μελέτησε λεπτομερώς τα αναδρομικά μοτίβα, τονίζοντας ένα γενικό σχέδιο σχεδίασης στο βιβλίο του - Recursion;
  • αναδρομικές συναρτήσεις (αλγόριθμοι) αυτοαποκαλούνται.

Το άρθρο είναι αφιερωμένο στην ανάλυση της πολυπλοκότητας των αναδρομικών αλγορίθμων, δίνονται οι απαραίτητες μαθηματικές πληροφορίες και εξετάζονται παραδείγματα. Επιπλέον, περιγράφεται η δυνατότητα αντικατάστασης της αναδρομής με έναν βρόχο, την αναδρομή ουράς.

Παραδείγματα αναδρομικών αλγορίθμων

Ένας αναδρομικός αλγόριθμος πάντα χωρίζει ένα πρόβλημα σε μέρη που είναι ίδια στη δομή με το αρχικό πρόβλημα, αλλά πιο απλά. Για την επίλυση υποπροβλημάτων, μια συνάρτηση καλείται αναδρομικά και τα αποτελέσματά της συνδυάζονται με κάποιο τρόπο. Η διαίρεση μιας εργασίας συμβαίνει μόνο όταν δεν μπορεί να επιλυθεί αμέσως (είναι πολύ περίπλοκη).

Για παράδειγμα, το έργο της επεξεργασίας ενός πίνακα μπορεί συχνά να περιοριστεί στην επεξεργασία των μερών του. Η διαίρεση σε μέρη πραγματοποιείται μέχρι να γίνουν στοιχειώδη, δηλ. αρκετά απλό για να έχετε το αποτέλεσμα χωρίς περαιτέρω απλοποίηση.

Εύρεση στοιχείου πίνακα

Αρχή; αναζήτηση (πίνακας, αρχή, τέλος, στοιχείο) ; αναζητά ένα στοιχείο με το στοιχείο τιμής στον πίνακα μεταξύ των δεικτών έναρξης και τέλους, εάν αρχή > τελικό αποτέλεσμα:= false; το στοιχείο δεν βρέθηκε διαφορετικά εάν πίνακας = αποτέλεσμα στοιχείου:= true; Βρέθηκε στοιχείο διαφορετικά αποτέλεσμα:= αναζήτηση (πίνακας, αρχή+1, τέλος, στοιχείο) τέλος; αποτέλεσμα επιστροφής

Ο αλγόριθμος χωρίζει τον αρχικό πίνακα σε δύο μέρη - το πρώτο στοιχείο και έναν πίνακα με τα υπόλοιπα στοιχεία. Υπάρχουν δύο απλές περιπτώσεις όπου δεν απαιτείται διαχωρισμός - όλα τα στοιχεία έχουν υποστεί επεξεργασία ή το πρώτο στοιχείο είναι αυτό που αναζητείται.

Στον αλγόριθμο αναζήτησης, ο πίνακας θα μπορούσε να χωριστεί διαφορετικά (για παράδειγμα, στο μισό), αλλά αυτό δεν θα επηρεάσει την αποτελεσματικότητα. Εάν ο πίνακας είναι ταξινομημένος, τότε συνιστάται η διαίρεση του στη μέση, γιατί Σε κάθε βήμα, ο όγκος των δεδομένων που υποβάλλονται σε επεξεργασία μπορεί να μειωθεί στο μισό.

Δυαδική αναζήτηση σε πίνακα

Η δυαδική αναζήτηση εκτελείται σε ταξινομημένο πίνακα. Σε κάθε βήμα, το στοιχείο που αναζητήθηκε συγκρίνεται με την τιμή που βρίσκεται στη μέση του πίνακα. Ανάλογα με τα αποτελέσματα της σύγκρισης, είτε η αριστερή είτε η δεξιά πλευρά μπορούν να «απορρίψουν».

Αρχή; binary_search(πίνακας, αρχή, τέλος, στοιχείο) ; αναζητά ένα στοιχείο με το στοιχείο τιμής ; σε έναν πίνακα ταξινομημένο σε πίνακα αύξουσας σειράς. μεταξύ των δεικτών αρχίζουν και τελειώνουν εάν αρχίζουν > τέλος τέλος. return false - το στοιχείο δεν βρέθηκε mid:= (end + start) div 2; υπολογισμός του δείκτη του στοιχείου στη μέση του εξεταζόμενου τμήματος του πίνακα εάν πίνακας = τέλος στοιχείου. επιστρέφει true (βρέθηκε στοιχείο) εάν πίνακας< element результат:= binary_search(array, mid+1, end, element) иначе результат:= binary_search(array, begin, mid, element) конец; вернуть результат

Υπολογισμός αριθμών Fibonacci

Οι αριθμοί Fibonacci καθορίζονται από μια επαναλαμβανόμενη έκφραση, δηλ. έτσι ώστε ο υπολογισμός του στοιχείου του οποίου να εκφράζεται από τα προηγούμενα στοιχεία: \(F_0 = 0, F_1 ​​= 1, F_n = F_(n-1) + F_(n-2), n > 2\).

Αρχή; fibonacci(αριθμός) εάν αριθμός = 0 τέλος; επιστροφή 0 εάν αριθμός = 1 τέλος. επιστροφή 1 fib_1:= fibonacci(αριθμός-1) fib_2:= fibonacci(αριθμός-2) αποτέλεσμα:= fib_1 + fib_2 τέλος; αποτέλεσμα επιστροφής

Γρήγορη ταξινόμηση

Σε κάθε βήμα, ο αλγόριθμος γρήγορης ταξινόμησης επιλέγει ένα από τα στοιχεία (την αναφορά) και σε σχέση με αυτό χωρίζει τον πίνακα σε δύο μέρη, τα οποία επεξεργάζονται αναδρομικά. Στο ένα μέρος τοποθετούνται στοιχεία μικρότερα από το υποστηρικτικό και στο άλλο τα υπόλοιπα.

Διάγραμμα ροής του αλγορίθμου γρήγορης ταξινόμησης

Συγχώνευση ταξινόμησης

Η βάση του αλγορίθμου ταξινόμησης συγχώνευσης είναι η δυνατότητα γρήγορου συνδυασμού διατεταγμένων πινάκων (ή λιστών) έτσι ώστε το αποτέλεσμα να ταξινομείται. Ο αλγόριθμος χωρίζει τον αρχικό πίνακα σε δύο μέρη τυχαία (συνήθως στο μισό), τα ταξινομεί αναδρομικά και συνδυάζει το αποτέλεσμα. Η διαίρεση συμβαίνει εφόσον το μέγεθος του πίνακα είναι μεγαλύτερο από ένα, επειδή ένας κενός πίνακας και ένας πίνακας ενός στοιχείου ταξινομούνται πάντα.

Μπλοκ διάγραμμα ταξινόμησης συγχώνευσης

Σε κάθε βήμα συγχώνευσης, επιλέγεται το πρώτο μη επεξεργασμένο στοιχείο και από τις δύο λίστες. Τα στοιχεία συγκρίνονται και το μικρότερο προστίθεται στο αποτέλεσμα και επισημαίνεται ως επεξεργασμένο. Η συγχώνευση πραγματοποιείται μέχρι να αδειάσει μία από τις λίστες.

Αρχή; συγχώνευση (Array1, Size1, Array2, Size2) ; οι αρχικοί πίνακες είναι διατεταγμένοι. το αποτέλεσμα είναι ένας διατεταγμένος πίνακας μήκους Size1+Size2 i:= 0, j:= 0 eternal_loop if i >= Size1 προσθέστε στοιχεία από το j στο Size2 του πίνακα Array2 στο τέλος του αποτελέσματος βγείτε από τον βρόχο εάν j >= Size2 προσθέστε στοιχεία από το i στο Size1 του πίνακα Array1 στο τέλος του αποτελέσματος βγείτε από τον βρόχο εάν Array1[i]< Array2[j] результат := Array1[i] i:= i + 1 иначе (если Array1[i] >= Array2[j]) αποτέλεσμα := Array2[j] j:= j + 1 end; αποτέλεσμα επιστροφής

Ανάλυση αναδρομικών αλγορίθμων

Όταν υπολογίζεται η πολυπλοκότητα των επαναλήψεων και ο αριθμός τους στις χειρότερες, καλύτερες και μέσες περιπτώσεις. Ωστόσο, δεν θα είναι δυνατή η εφαρμογή αυτής της προσέγγισης σε μια αναδρομική συνάρτηση, επειδή το αποτέλεσμα θα είναι μια σχέση επανάληψης. Για παράδειγμα, για τη συνάρτηση που αναζητά ένα στοιχείο σε έναν πίνακα:

\(
\αρχή(εξίσωση*)
T^(αναζήτηση)_n = \begin(περιπτώσεις)
\mathcal(O)(1) \quad &\text($n = 0$) \\
\mathcal(O)(1) + \mathcal(O)(T^(αναζήτηση)_(n-1)) \quad &\text($n > 0$)
\end (περιπτώσεις)
\end(εξίσωση*)
\)

Οι επαναλαμβανόμενες σχέσεις δεν μας επιτρέπουν να αξιολογήσουμε την πολυπλοκότητα - δεν μπορούμε απλώς να τις συγκρίνουμε και επομένως να συγκρίνουμε την αποτελεσματικότητα των αντίστοιχων αλγορίθμων. Είναι απαραίτητο να ληφθεί ένας τύπος που περιγράφει την επαναλαμβανόμενη σχέση - ένας καθολικός τρόπος για να γίνει αυτό είναι να επιλέξετε τον τύπο χρησιμοποιώντας τη μέθοδο αντικατάστασης και στη συνέχεια να αποδείξετε την αντιστοιχία του τύπου στη σχέση χρησιμοποιώντας τη μέθοδο της μαθηματικής επαγωγής.

Μέθοδος αντικατάστασης (επανάληψης).

Συνίσταται στη διαδοχική αντικατάσταση του επαναλαμβανόμενου τμήματος σε μια έκφραση για τη λήψη νέων εκφράσεων. Η αντικατάσταση γίνεται έως ότου καταστεί δυνατή η κατανόηση της γενικής αρχής και η έκφραση της με τη μορφή ενός μη επαναλαμβανόμενου τύπου. Για παράδειγμα, για να αναζητήσετε ένα στοιχείο σε έναν πίνακα:

\(
T^(αναζήτηση)_n = \mathcal(O)(1) + \mathcal(O)(T^(αναζήτηση)_(n-1)) =
2\times\mathcal(O)(1) + \mathcal(O)(T^(αναζήτηση)_(n-2)) =
3\times\mathcal(O)(1) + \mathcal(O)(T^(αναζήτηση)_(n-3))
\)

Μπορούμε να υποθέσουμε ότι \(T^(αναζήτηση)_n = T^(αναζήτηση)_(n-k) + k\times\mathcal(O)(1)\), αλλά τότε \(T^(αναζήτηση)_n = T^ (αναζήτηση)_(0) + n\times\mathcal(O)(1) = \mathcal(O)(n)\).

Εξάγαμε τον τύπο, αλλά το πρώτο βήμα περιέχει μια υπόθεση, δηλ. δεν υπάρχει απόδειξη της αντιστοιχίας του τύπου με την επαναλαμβανόμενη έκφραση - η μέθοδος της μαθηματικής επαγωγής μας επιτρέπει να λάβουμε την απόδειξη.

Μέθοδος μαθηματικής επαγωγής

Σας επιτρέπει να αποδείξετε την αλήθεια μιας συγκεκριμένης δήλωσης (\(P_n\)), που αποτελείται από δύο βήματα:

  1. απόδειξη της δήλωσης για μία ή περισσότερες ειδικές περιπτώσεις \(P_0, P_1, …\)·
  2. από την αλήθεια του \(P_n\) (επαγωγική υπόθεση) και τις ειδικές περιπτώσεις, συνάγεται η απόδειξη του \(P_(n+1)\).

Ας αποδείξουμε την ορθότητα της υπόθεσης που έγινε κατά την εκτίμηση της πολυπλοκότητας της συνάρτησης αναζήτησης (\(T^(αναζήτηση)_n = (n+1)\times\mathcal(O)(1)\)):

  1. \(T^(αναζήτηση)_(1) = 2\times\mathcal(O)(1)\) ισχύει από τη συνθήκη (μπορεί να αντικατασταθεί στον αρχικό επαναλαμβανόμενο τύπο).
  2. ας υποθέσουμε την αλήθεια \(T^(αναζήτηση)_n = (n+1)\times\mathcal(O)(1)\);
  3. πρέπει να αποδείξουμε ότι \(T^(αναζήτηση)_(n+1) = ((n+1)+1)\times\mathcal(O)(1) = (n+2)\times\mathcal(O ) (1)\);
    1. Ας αντικαταστήσουμε το \(n+1\) στη σχέση επανάληψης: \(T^(αναζήτηση)_(n+1) = \mathcal(O)(1) + T^(αναζήτηση)_n\);
    2. στη δεξιά πλευρά της έκφρασης είναι δυνατό να γίνει αντικατάσταση με βάση την επαγωγική υπόθεση: \(T^(αναζήτηση)_(n+1) = \mathcal(O)(1) + (n+1)\times \mathcal(O)(1) = (n+2)\times\mathcal(O)(1)\);
    3. η δήλωση έχει αποδειχθεί.

Συχνά, μια τέτοια απόδειξη είναι μια μάλλον εντατική διαδικασία, αλλά είναι ακόμη πιο δύσκολο να προσδιοριστεί ένα μοτίβο χρησιμοποιώντας τη μέθοδο υποκατάστασης. Από αυτή την άποψη, χρησιμοποιείται η λεγόμενη γενική μέθοδος.

Γενική (βασική) μέθοδος επίλυσης σχέσεων υποτροπής

Η γενική μέθοδος δεν είναι καθολική, για παράδειγμα, δεν μπορεί να χρησιμοποιηθεί για την εκτίμηση της πολυπλοκότητας του παραπάνω αλγορίθμου για τον υπολογισμό των αριθμών Fibonacci. Ωστόσο, ισχύει για όλες τις περιπτώσεις χρήσης της προσέγγισης διαίρει και βασίλευε:

\(T_n = a\cdot T(\frac(n)(b))+f_n; a, b = const, a \geq 1, b > 1, f_n > 0, \forall n\).

Οι εξισώσεις αυτού του τύπου λαμβάνονται εάν το αρχικό πρόβλημα χωριστεί σε υποεργασίες, καθεμία από τις οποίες επεξεργάζεται στοιχεία \(\frac(n)(b)\). Το \(f_n\) είναι η πολυπλοκότητα των λειτουργιών της διαίρεσης του προβλήματος σε μέρη και του συνδυασμού λύσεων. Εκτός από τον τύπο της σχέσης, η γενική μέθοδος επιβάλλει περιορισμούς στη συνάρτηση \(f_n\), διακρίνοντας τρεις περιπτώσεις:

  1. \(\υπάρχει \varepsilon > 0: f_n = \mathcal(O)(n^(\log_b a - \varepsilon)) \Δεξί βέλος T_n = \Theta(n^(\log_b a))\);
  2. \(f_n = \Theta(n^(\log_b a)) \Δεξί βέλος T_n = \Theta(n^(\log_b a) \cdot \log n)\);
  3. \(\υπάρχει \varepsilon > 0, γ< 1: f_n = \Omega(n^{\log_b a + \varepsilon}), f_{\frac{n}{b}} \leq c \cdot f_n \Rightarrow T_n = \Theta(f_n)\).

Η ορθότητα των δηλώσεων για κάθε περίπτωση αποδεικνύεται τυπικά. Το έργο της ανάλυσης ενός αναδρομικού αλγορίθμου καταλήγει τώρα στον προσδιορισμό της περίπτωσης του κύριου θεωρήματος στο οποίο αντιστοιχεί η σχέση επανάληψης.

Ανάλυση του δυαδικού αλγορίθμου αναζήτησης

Ο αλγόριθμος χωρίζει τα δεδομένα προέλευσης σε 2 μέρη (b = 2), αλλά επεξεργάζεται μόνο ένα από αυτά (a = 1), \(f_n = 1\). \(n^(\log_b a) = n^(\log_2 1) = n^0 = 1\). Η συνάρτηση της διαίρεσης της εργασίας και της τακτοποίησης του αποτελέσματος αυξάνεται με τον ίδιο ρυθμό με το \(n^(\log_b a)\), που σημαίνει ότι είναι απαραίτητο να χρησιμοποιηθεί η δεύτερη περίπτωση του θεωρήματος:

\(T^(binarySearch)_n = \Theta(n^(\log_b a) \cdot \log n) = \Theta(1 \cdot \log n) = \Theta(\log n)\).

Ανάλυση αλγορίθμου αναζήτησης

Η αναδρομική συνάρτηση χωρίζει το αρχικό πρόβλημα σε μία υποεργασία (a = 1), τα δεδομένα χωρίζονται σε ένα μέρος (b = 1). Δεν μπορούμε να χρησιμοποιήσουμε το κύριο θεώρημα για να αναλύσουμε αυτόν τον αλγόριθμο, γιατί η συνθήκη \(b > 1\) δεν ικανοποιείται.

Για τη διεξαγωγή της ανάλυσης, μπορεί να χρησιμοποιηθεί η μέθοδος αντικατάστασης ή ο ακόλουθος συλλογισμός: κάθε αναδρομική κλήση μειώνει τη διάσταση των δεδομένων εισόδου κατά ένα, πράγμα που σημαίνει ότι θα υπάρχουν συνολικά n τεμάχια, καθένα από τα οποία έχει πολυπλοκότητα \(\mathcal( Ο)(1)\). Τότε \(T^(αναζήτηση)_n = n \cdot \mathcal(O)(1) = \mathcal(O)(n)\).

Ανάλυση του αλγόριθμου ταξινόμησης συγχώνευσης

Τα δεδομένα προέλευσης χωρίζονται σε δύο μέρη, τα οποία υποβάλλονται σε επεξεργασία και τα δύο: \(a = 2, b = 2, n^(\log_b a) = n\).

Κατά την επεξεργασία μιας λίστας, η διαίρεση μπορεί να απαιτεί λειτουργίες \(\Theta(n)\), ενώ για έναν πίνακα χρειάζεται σταθερός χρόνος (\(\Theta(1)\)). Ωστόσο, σε κάθε περίπτωση, το \(\Theta(n)\) θα δαπανηθεί για τη σύνδεση των αποτελεσμάτων, οπότε \(f_n = n\).

Χρησιμοποιείται η δεύτερη περίπτωση του θεωρήματος: \(T^(mergeSort)_n = \Theta(n^(\log_b a) \cdot \log n) = \Theta(n \cdot \log n)\).

Ανάλυση της έντασης εργασίας γρήγορης κατηγορίας

Στην καλύτερη περίπτωση, ο αρχικός πίνακας χωρίζεται σε δύο μέρη, καθένα από τα οποία περιέχει τα μισά από τα αρχικά δεδομένα. Η διαίρεση θα απαιτήσει n λειτουργίες. Η πολυπλοκότητα της σύνθεσης του αποτελέσματος εξαρτάται από τις δομές δεδομένων που χρησιμοποιούνται - για έναν πίνακα \(\mathcal(O)(n)\), για μια συνδεδεμένη λίστα \(\mathcal(O)(1)\). \(a = 2, b = 2, f_n = b\), που σημαίνει ότι η πολυπλοκότητα του αλγορίθμου θα είναι ίδια με αυτή της ταξινόμησης συγχώνευσης: \(T^(quickSort)_n = \mathcal(O)(n \ cdot \log n)\ ).

Ωστόσο, στη χειρότερη περίπτωση, το ελάχιστο ή μέγιστο στοιχείο του πίνακα θα επιλέγεται συνεχώς ως αναφορά. Τότε \(b = 1\), που σημαίνει ότι δεν μπορούμε και πάλι να χρησιμοποιήσουμε το κύριο θεώρημα. Ωστόσο, γνωρίζουμε ότι σε αυτή την περίπτωση θα γίνουν n αναδρομικές κλήσεις, καθεμία από τις οποίες χωρίζει τον πίνακα σε μέρη (\(\mathcal(O)(n)\)) - που σημαίνει την πολυπλοκότητα του αλγορίθμου \(T^( quickSort)_n = \mathcal(O)(n^2)\).

Κατά την ανάλυση της γρήγορης ταξινόμησης με αντικατάσταση, θα πρέπει επίσης να ληφθούν υπόψη οι καλύτερες και οι χειρότερες περιπτώσεις ξεχωριστά.

Αναδρομή ουράς και βρόχος

Η ανάλυση της πολυπλοκότητας των αναδρομικών συναρτήσεων είναι πολύ πιο περίπλοκη από την αξιολόγηση των βρόχων, αλλά ο κύριος λόγος για τον οποίο οι βρόχοι είναι προτιμότεροι είναι το υψηλό κόστος της κλήσης μιας συνάρτησης.

Μετά την κλήση ο έλεγχος μεταφέρεταιάλλη λειτουργία. Για να μεταφέρετε τον έλεγχο, αρκεί να αλλάξετε την τιμή του καταχωρητή μετρητή προγράμματος, στον οποίο ο επεξεργαστής αποθηκεύει τον αριθμό της εντολής που εκτελείται - με τον ίδιο τρόπο, ο έλεγχος μεταφέρεται στους κλάδους του αλγορίθμου, για παράδειγμα, όταν χρησιμοποιείται ένας τελεστής υπό όρους. Ωστόσο, μια κλήση δεν είναι μόνο μεταφορά ελέγχου, γιατί αφού η καλούμενη συνάρτηση ολοκληρώσει τους υπολογισμούς της, πρέπει έλεγχος επιστροφήςμέχρι το σημείο όπου έγινε η κλήση και επίσης επαναφέρετε τις τιμές των τοπικών μεταβλητών που υπήρχαν εκεί πριν από την κλήση.

Για την υλοποίηση αυτής της συμπεριφοράς, χρησιμοποιείται μια στοίβα (στοίβα κλήσεων) - ο αριθμός εντολής προς επιστροφή και πληροφορίες σχετικά με τις τοπικές μεταβλητές τοποθετούνται σε αυτήν. Η στοίβα δεν είναι άπειρη, επομένως οι αναδρομικοί αλγόριθμοι μπορούν να οδηγήσουν σε υπερχείλιση στοίβας και σε κάθε περίπτωση, η εργασία με αυτήν μπορεί να διαρκέσει σημαντικό χρόνο.

Σε ορισμένες περιπτώσεις, είναι πολύ εύκολο να αντικαταστήσετε μια αναδρομική συνάρτηση με έναν βρόχο, για παράδειγμα, αυτούς που συζητήθηκαν παραπάνω. Σε ορισμένες περιπτώσεις, απαιτείται μια πιο δημιουργική προσέγγιση, αλλά τις περισσότερες φορές είναι δυνατή μια τέτοια αντικατάσταση. Επιπλέον, υπάρχει ένα ειδικό είδος αναδρομής όπου η αναδρομική κλήση είναι η τελευταία λειτουργία που εκτελείται από τη συνάρτηση. Προφανώς, σε αυτήν την περίπτωση, η συνάρτηση κλήσης δεν θα αλλάξει το αποτέλεσμα με κανέναν τρόπο, πράγμα που σημαίνει ότι δεν υπάρχει λόγος να επιστρέψετε τον έλεγχο. Τέτοιος η αναδρομή ονομάζεται αναδρομή ουράς— οι μεταγλωττιστές το αντικαθιστούν αυτόματα με έναν βρόχο.

Συχνά βοηθά να κάνετε μια υποτροπή της ουράς μέθοδος συσσωρευτικής παραμέτρου, η οποία συνίσταται στην προσθήκη μιας πρόσθετης συνάρτησης ορίσματος συσσωρευτή στην οποία συσσωρεύεται το αποτέλεσμα. Η συνάρτηση εκτελεί υπολογισμούς στον συσσωρευτή πριν από την αναδρομική κλήση. Ένα καλό παράδειγμα χρήσης αυτής της τεχνικής είναι η παραγοντική συνάρτηση:
\(γεγονός_n = n \cdot γεγονός(n-1) \\
fact_3 = 3 \cdot fact_2 = 3 \cdot (2 \cdot fact_1) = 3\cdot (2 \cdot (1 \cdot fact_0)) = 6 \\
fact_n = factTail_(n, 1) \\
\\
factTail_(n, accumulator) = factTail(n-1, accumulator \cdot n)\\
factTail_(3, 1) = factTail_(2, 3) = factTail_(1, 6) = factTail_(0, 6) = 6
\)

Ως πιο περίπλοκο παράδειγμα, εξετάστε τη συνάρτηση για τον υπολογισμό των αριθμών Fibonacci. Η κύρια συνάρτηση καλεί μια βοηθητική συνάρτηση που χρησιμοποιεί τη μέθοδο της παραμέτρου συσσώρευσης, περνώντας την αρχική τιμή του επαναλήπτη και δύο συσσωρευτές (τους δύο προηγούμενους αριθμούς Fibonacci) ως ορίσματα.

Αρχή; fibonacci(number) return fibonacci(number, 1, 1, 0) end start? fibonacci(αριθμός, επαναλήπτης, fib1, fib2) αν επαναλήπτης == αριθμός επιστροφής fib1 επιστροφή fibonacci(αριθμός, επαναλήπτης + 1, fib1 + fib2, fib1) τέλος

Μια συνάρτηση με παράμετρο συσσώρευσης επιστρέφει το συσσωρευμένο αποτέλεσμα εάν υπολογιστεί ένας καθορισμένος αριθμός αριθμών, διαφορετικά αυξάνει τον μετρητή, υπολογίζει έναν νέο αριθμό Fibonacci και πραγματοποιεί μια αναδρομική κλήση. Οι μεταγλωττιστές βελτιστοποίησης ενδέχεται να ανιχνεύσουν ότι το αποτέλεσμα μιας κλήσης συνάρτησης μεταβιβάζεται αμετάβλητο στην έξοδο της συνάρτησης και να το αντικαταστήσει με έναν βρόχο. Αυτή η τεχνική είναι ιδιαίτερα σημαντική σε λειτουργικές και λογικές γλώσσες προγραμματισμού, επειδή σε αυτά ο προγραμματιστής δεν μπορεί να χρησιμοποιήσει ρητά κυκλικές κατασκευές.

Βιβλιογραφία

  1. Διακομιστής Qt πολλαπλών νημάτων. Πισίνα με νήματα. Μοτίβο διακοσμητή[Ηλεκτρονικός πόρος] - λειτουργία πρόσβασης: https://site/archives/1390. Ημερομηνία πρόσβασης: 21/02/2015.
  2. Jason McColm Smith: Μετάφρ. από τα Αγγλικά - M.: LLC «I.D. Williams”, 2013. - 304 σελ.
  3. Skiena S. Αλγόριθμοι. Οδηγός Ανάπτυξης.-2η έκδ.: μτφρ. από αγγλικά-SPb.: BHV-Petersburg, 2011.-720 σελ.: ill.
  4. Vasiliev V. S. Ανάλυση της πολυπλοκότητας των αλγορίθμων. Παραδείγματα [Ηλεκτρονικός πόρος] - λειτουργία πρόσβασης: https://site/archives/1660. Ημερομηνία πρόσβασης: 21/02/2015.
  5. A. Aho, J. Hopcroft, J. Ullman, Δομές δεδομένων και αλγόριθμοι, M., Williams, 2007.
  6. Miller, R. Διαδοχικοί και παράλληλοι αλγόριθμοι: Μια γενική προσέγγιση / R. Miller, L. Boxer; λωρίδα από τα Αγγλικά - Μ.: ΜΠΙΝΟΜ. Εργαστήριο Γνώσης, 2006. - 406 σελ.
  7. Sergievsky G.M. Λειτουργικός και λογικός προγραμματισμός: σχολικό βιβλίο. εγχειρίδιο για φοιτητές τριτοβάθμιας εκπαίδευσης εγχειρίδιο εγκαταστάσεις / Γ.Μ. Sergievsky, N.G. Βολτσένκοφ. - Μ.: Εκδοτικό κέντρο «Ακαδημία», 2010.- 320 σελ.

Γεια σου Habrahabr!

Σε αυτό το άρθρο θα μιλήσουμε για προβλήματα αναδρομής και πώς να τα λύσουμε.

Συνοπτικά για την αναδρομή

Η αναδρομή είναι ένα αρκετά συχνό φαινόμενο που εμφανίζεται όχι μόνο στους τομείς της επιστήμης, αλλά και στην καθημερινή ζωή. Για παράδειγμα, το φαινόμενο Droste, το τρίγωνο Sierpinski, κ.λπ. Ένας τρόπος για να δείτε την αναδρομή είναι να στρέψετε την κάμερα Web στην οθόνη της οθόνης του υπολογιστή, φυσικά, αφού την έχετε ενεργοποιήσει πρώτα. Έτσι, η κάμερα θα καταγράψει την εικόνα της οθόνης του υπολογιστή και θα την εμφανίσει σε αυτήν την οθόνη, θα είναι κάτι σαν κλειστός βρόχος. Ως αποτέλεσμα, θα παρατηρήσουμε κάτι παρόμοιο με ένα τούνελ.

Στον προγραμματισμό, η αναδρομή σχετίζεται στενά με τις συναρτήσεις, χάρη στις συναρτήσεις στον προγραμματισμό υπάρχει κάτι όπως η αναδρομή ή μια αναδρομική συνάρτηση. Με απλά λόγια, η αναδρομή είναι ο ορισμός ενός μέρους μιας συνάρτησης (μέθοδος) μέσω του εαυτού της, δηλαδή είναι μια συνάρτηση που αυτοαποκαλείται, άμεσα (στο σώμα της) ή έμμεσα (μέσω άλλης συνάρτησης).

Πολλά έχουν ειπωθεί για την αναδρομή. Εδώ είναι μερικοί καλοί πόροι:

  • Αναδρομικά και αναδρομικά προβλήματα. Τομείς εφαρμογής της αναδρομής
Υποτίθεται ότι ο αναγνώστης είναι θεωρητικά εξοικειωμένος με την αναδρομή και γνωρίζει τι είναι. Σε αυτό το άρθρο θα δώσουμε μεγαλύτερη προσοχή στα προβλήματα αναδρομής.

Καθήκοντα

Όταν μαθαίνουμε την αναδρομή, ο πιο αποτελεσματικός τρόπος για να κατανοήσουμε την αναδρομή είναι η επίλυση προβλημάτων.
Πώς να λύσετε προβλήματα αναδρομής;
Πρώτα απ 'όλα, πρέπει να καταλάβετε ότι η αναδρομή είναι ένα είδος υπερβολής. Σε γενικές γραμμές, οτιδήποτε λύνεται επαναληπτικά μπορεί να λυθεί αναδρομικά, δηλαδή χρησιμοποιώντας μια αναδρομική συνάρτηση.

από το δίκτυο

Οποιοσδήποτε αλγόριθμος υλοποιείται σε αναδρομική μορφή μπορεί να ξαναγραφτεί σε επαναληπτική μορφή και αντίστροφα. Το ερώτημα παραμένει αν αυτό είναι απαραίτητο και πόσο αποτελεσματικό θα είναι.

Τα ακόλουθα επιχειρήματα μπορούν να δοθούν για να το δικαιολογήσουν αυτό.

Αρχικά, μπορούμε να θυμηθούμε τους ορισμούς της αναδρομής και της επανάληψης. Η αναδρομή είναι ένας τρόπος οργάνωσης της επεξεργασίας δεδομένων στον οποίο ένα πρόγραμμα καλεί τον εαυτό του απευθείας ή με τη βοήθεια άλλων προγραμμάτων. Η επανάληψη είναι ένας τρόπος οργάνωσης της επεξεργασίας δεδομένων κατά τον οποίο ορισμένες ενέργειες επαναλαμβάνονται πολλές φορές χωρίς να οδηγούν σε αναδρομικές κλήσεις προγράμματος.

Μετά από αυτό μπορούμε να συμπεράνουμε ότι είναι αμοιβαία εναλλάξιμα, αλλά όχι πάντα με το ίδιο κόστος όσον αφορά τους πόρους και την ταχύτητα. Για να το δικαιολογήσουμε αυτό, μπορούμε να δώσουμε το ακόλουθο παράδειγμα: υπάρχει μια συνάρτηση στην οποία, για να οργανωθεί ένας συγκεκριμένος αλγόριθμος, υπάρχει ένας βρόχος που εκτελεί μια ακολουθία ενεργειών ανάλογα με την τρέχουσα τιμή του μετρητή (μπορεί να μην εξαρτάται από το). Εφόσον υπάρχει κύκλος, σημαίνει ότι το σώμα επαναλαμβάνει μια σειρά ενεργειών - επαναλήψεις του κύκλου. Μπορείτε να μετακινήσετε λειτουργίες σε μια ξεχωριστή υπορουτίνα και να της μεταβιβάσετε την τιμή του μετρητή, εάν υπάρχει. Με την ολοκλήρωση της εκτέλεσης της υπορουτίνας, ελέγχουμε τις συνθήκες για την εκτέλεση του βρόχου και εάν είναι αληθές, προχωράμε σε νέα κλήση στην υπορουτίνα, αν είναι false, ολοκληρώνουμε την εκτέλεση. Επειδή Τοποθετήσαμε όλα τα περιεχόμενα του βρόχου σε μια υπορουτίνα, που σημαίνει ότι η συνθήκη για την εκτέλεση του βρόχου τοποθετείται επίσης στην υπορουτίνα και μπορεί να ληφθεί μέσω της τιμής επιστροφής της συνάρτησης, των παραμέτρων που περνούν με αναφορά ή δείκτη στην υπορουτίνα , καθώς και καθολικές μεταβλητές. Επιπλέον, είναι εύκολο να δείξουμε ότι μια κλήση σε μια δεδομένη υπορουτίνα από έναν βρόχο μπορεί εύκολα να μετατραπεί σε κλήση ή μη κλήση (επιστρέφοντας μια τιμή ή απλώς ολοκληρώνοντας την εργασία) μιας υπορουτίνας από τον εαυτό της, καθοδηγούμενη από ορισμένες συνθήκες (αυτές που ήταν προηγουμένως σε κατάσταση βρόχου). Τώρα, αν κοιτάξετε το αφηρημένο πρόγραμμά μας, μοιάζει κατά προσέγγιση σαν να περνάμε τιμές σε μια υπορουτίνα και να τις χρησιμοποιείτε, τις οποίες η υπορουτίνα θα αλλάξει όταν τελειώσει, π.χ. Αντικαταστήσαμε τον επαναληπτικό βρόχο με μια αναδρομική κλήση σε μια υπορουτίνα για να λύσουμε έναν δεδομένο αλγόριθμο.

Το έργο της επαναφοράς σε μια επαναληπτική προσέγγιση είναι συμμετρικό.

Συνοψίζοντας, μπορούμε να εκφράσουμε τις ακόλουθες σκέψεις: για κάθε προσέγγιση υπάρχει η δική της κατηγορία εργασιών, η οποία καθορίζεται από τις συγκεκριμένες απαιτήσεις για μια συγκεκριμένη εργασία.

Μπορείτε να μάθετε περισσότερα για αυτό


Ακριβώς όπως μια απαρίθμηση (κύκλος), η αναδρομή πρέπει να έχει μια συνθήκη διακοπής - Βασική περίπτωση (διαφορετικά, ακριβώς όπως ένας κύκλος, η αναδρομή θα λειτουργεί για πάντα - άπειρη). Αυτή η συνθήκη είναι η περίπτωση στην οποία πηγαίνει η αναδρομή (βήμα αναδρομής). Σε κάθε βήμα, καλείται μια αναδρομική συνάρτηση έως ότου η επόμενη κλήση ενεργοποιήσει τη βασική συνθήκη και η αναδρομή σταματήσει (ή μάλλον, επιστρέψει στην τελευταία κλήση συνάρτησης). Η όλη λύση καταλήγει στην επίλυση της βασικής υπόθεσης. Στην περίπτωση που μια αναδρομική συνάρτηση καλείται να λύσει ένα σύνθετο πρόβλημα (όχι τη βασική περίπτωση), εκτελείται ένας αριθμός αναδρομικών κλήσεων ή βημάτων προκειμένου να μειωθεί το πρόβλημα σε απλούστερο. Και ούτω καθεξής μέχρι να πάρουμε μια βασική λύση.

Άρα η αναδρομική συνάρτηση αποτελείται από

  • Κατάσταση στάσης ή θήκη βάσης
  • Μια συνθήκη συνέχισης ή ένα βήμα αναδρομής είναι ένας τρόπος μείωσης ενός προβλήματος σε απλούστερα.
Ας το δούμε αυτό χρησιμοποιώντας το παράδειγμα εύρεσης του παραγοντικού:

Λύση δημόσιας κλάσης ( public static int recursion(int n) ( // συνθήκη εξόδου // Βασική περίπτωση // πότε να σταματήσει η επανάληψη της αναδρομής; if (n == 1) ( return 1; ) // Recursion step / recursive condition return recursion( n - 1) * n ) public static void main (String args) ( System.out.println(recursion(5)); // κλήση μιας αναδρομικής συνάρτησης ) )

Εδώ η Βασική συνθήκη είναι η συνθήκη όταν n=1. Αφού ξέρουμε ότι 1!=1 και να υπολογίσουμε 1! δεν χρειαζόμαστε τίποτα. Να υπολογίσω 2! μπορούμε να χρησιμοποιήσουμε 1!, δηλ. 2!=1!*2. Για να υπολογίσετε 3! χρειαζόμαστε 2!*3... Για να υπολογίσουμε το ν! χρειαζόμαστε (n-1)!*n. Αυτό είναι το βήμα της αναδρομής. Με άλλα λόγια, για να λάβουμε την παραγοντική τιμή ενός αριθμού n, αρκεί να πολλαπλασιάσουμε την παραγοντική τιμή του προηγούμενου αριθμού επί n.

Ετικέτες:

  • αναδρομή
  • καθήκοντα
  • Ιάβα
Προσθέστε ετικέτες

Λειτουργίες: αναδρομικά δίνεταιΜια συνάρτηση στον ορισμό της περιέχει τον εαυτό της συγκεκριμένα, μια συνάρτηση που ορίζεται από έναν επαναλαμβανόμενο τύπο είναι αναδρομική. Έτσι, σε μία έκφραση μπορείτε να δώσετε ένα άπειρο σύνολο τρόπων για τον υπολογισμό μιας συνάρτησης, να ορίσετε πολλά αντικείμενα μέσω του εαυτού σας χρησιμοποιώντας ιδιωτικούς ορισμούς που καθορίστηκαν προηγουμένως.

Δεδομένα

Struct element_of_list ( element_of_list * next; /* αναφορά στο επόμενο στοιχείο του ίδιου τύπου */ int δεδομένα? /* ορισμένα δεδομένα */ );

Η αναδρομική δομή των δεδομένων συχνά υπαγορεύει τη χρήση της αναδρομής για την επεξεργασία των δεδομένων.

Στη φυσική

Ένα κλασικό παράδειγμα άπειρης αναδρομής είναι δύο καθρέφτες τοποθετημένοι ο ένας απέναντι από τον άλλο: σχηματίζουν δύο διαδρόμους φθίνουσας ανάκλασης των κατόπτρων.

Ένα άλλο παράδειγμα άπειρης αναδρομής είναι η επίδραση της αυτοδιέγερσης (θετική ανάδραση) στα ηλεκτρονικά κυκλώματα ενίσχυσης, όταν το σήμα από την έξοδο πηγαίνει στην είσοδο, ενισχύεται, επιστρέφει στην είσοδο του κυκλώματος και ενισχύεται ξανά. Οι ενισχυτές για τους οποίους αυτός ο τρόπος λειτουργίας είναι στάνταρ ονομάζονται αυτοταλαντωτές.

Στη γλωσσολογία

Η ικανότητα μιας γλώσσας να δημιουργεί ένθετες προτάσεις και κατασκευές. Βασική προσφορά" η γάτα έφαγε το ποντίκι» μπορεί να επεκταθεί με αναδρομή ως Ο Βάνια μάντεψε ότι η γάτα έφαγε το ποντίκι, στη συνέχεια ως Η Κάτια ξέρει ότι ο Βάνια μάντεψε ότι η γάτα έφαγε το ποντίκικαι ούτω καθεξής. Η αναδρομή θεωρείται ένα από τα γλωσσικά καθολικά, δηλαδή είναι χαρακτηριστικό κάθε φυσικής γλώσσας. Ωστόσο, πρόσφατα υπήρξε ενεργή συζήτηση για την πιθανή απουσία αναδρομής σε μια από τις γλώσσες του Αμαζονίου - Pirahã, η οποία σημειώνεται από τον γλωσσολόγο Daniel Everett ( Αγγλικά) .

Στον πολιτισμό

Τα περισσότερα αστεία σχετικά με την αναδρομή αφορούν την άπειρη αναδρομή, στην οποία δεν υπάρχει συνθήκη εξόδου, για παράδειγμα, το διάσημο ρητό: «για να καταλάβεις την αναδρομή, πρέπει πρώτα να καταλάβεις την αναδρομή».

Ένα πολύ δημοφιλές αστείο για την αναδρομή, που θυμίζει λήμμα λεξικού:

Αρκετές ιστορίες του Stanislaw Lem είναι αφιερωμένες σε (πιθανά) περιστατικά με άπειρη αναδρομή:

  • η ιστορία για τον Ion the Quiet "The Fourteenth Journey" από τα "Star Diaries of Iyon the Quiet", στην οποία ο ήρωας μετακινείται διαδοχικά από ένα άρθρο για το sepulki σε ένα άρθρο για το sepullation, από εκεί σε ένα άρθρο για το sepulcaria, το οποίο περιέχει και πάλι αναφορά στο άρθρο «sepulki»:

Βρήκα τις ακόλουθες σύντομες πληροφορίες:
«Οι ΣΕΠΟΥΛΚΙ αποτελούν σημαντικό στοιχείο του Αρδρίτη πολιτισμού (q.v.) από τον πλανήτη Εντεροπία (q.v.). Βλέπε SEPULCARIA."
Ακολούθησα αυτή τη συμβουλή και διάβασα:
"SEPULCARIA - συσκευές για απομάκρυνση (βλ.)"
Έψαξα για "Sepulenia"? διάβαζε:
«SEPULATION είναι η κατάληψη των Αρδριτών (q.v.) από τον πλανήτη Enteropia (q.v.). Δείτε SEPULS."

Lem S. «Star Diaries of Iyon the Quiet. Ταξίδι δεκατέσσερα».

  • Μια ιστορία από το "Cyberiad" για μια έξυπνη μηχανή που είχε αρκετή ευφυΐα και τεμπελιά για να κατασκευάσει μια παρόμοια για να λύσει ένα δεδομένο πρόβλημα και να της εμπιστευτεί τη λύση (το αποτέλεσμα ήταν μια ατελείωτη αναδρομή, όταν κάθε νέα μηχανή κατασκεύαζε μια παρόμοια και του ανέθεσε το καθήκον).
  • Αναδρομικά ακρωνύμια: GNU (GNU Not Unix), PHP (PHP: Hypertext Preprocessor) κ.λπ.

δείτε επίσης

  • Ακολουθία επιστροφής

Σημειώσεις


Ίδρυμα Wikimedia. 2010.

Δείτε τι είναι το "Recursion" σε άλλα λεξικά:

    Επιστροφή, επανάληψη Λεξικό ρωσικών συνωνύμων. αναδρομικό ουσιαστικό, αριθμός συνωνύμων: 1 ... Συνώνυμο λεξικό

    αναδρομή- - [] αναδρομή Με μια γενική έννοια, ο υπολογισμός μιας συνάρτησης χρησιμοποιώντας έναν συγκεκριμένο αλγόριθμο. Παραδείγματα τέτοιων αλγορίθμων είναι επαναλαμβανόμενοι τύποι που εξάγουν τον υπολογισμό ενός δεδομένου όρου... ... Οδηγός Τεχνικού Μεταφραστή

    Αναδρομή- κατά γενική έννοια, ο υπολογισμός μιας συνάρτησης με χρήση συγκεκριμένου αλγόριθμου. Παραδείγματα τέτοιων αλγορίθμων είναι επαναλαμβανόμενοι τύποι, οι οποίοι αντλούν τον υπολογισμό ενός δεδομένου όρου μιας ακολουθίας (συνήθως αριθμητικό) από τον υπολογισμό πολλών προηγούμενων ... Οικονομικό και μαθηματικό λεξικό

    Αναδρομή- Ένα θεραπευτικό πρότυπο στο οποίο κάποια κατάσταση ή κριτήριο που διατυπώθηκε στην αρχική δήλωση λαμβάνεται και εφαρμόζεται στην ίδια τη δήλωση. Για παράδειγμα: Δεν έχω χρόνο. Πόσο χρόνο χρειάστηκε να ξοδέψετε για να βεβαιωθείτε ότι... ... Μεγάλη ψυχολογική εγκυκλοπαίδεια

    Μια μέθοδος προσδιορισμού συναρτήσεων, που αποτελεί αντικείμενο μελέτης στη θεωρία των αλγορίθμων και σε άλλους κλάδους των μαθηματικών. λογική. Αυτή η μέθοδος έχει χρησιμοποιηθεί από καιρό στην αριθμητική για τον προσδιορισμό αριθμητικών ακολουθιών (πρόοδος, αριθμοί Fibonacci, κ.λπ.).... ... Μαθηματική Εγκυκλοπαίδεια

    αναδρομή- (φόντο) (λατ. recursio επιστροφή). Μία από τις τρεις φάσεις της άρθρωσης του ήχου, η εσοχή. Μεταφορά των οργάνων ομιλίας σε ήρεμη κατάσταση ή έναρξη της άρθρωσης του επόμενου ήχου. Στη λέξη υπόλοιπο, η αναδρομή (εσοχή) κατά την άρθρωση [t] μπορεί να επικαλύπτεται ... ... Λεξικό γλωσσικών όρων T.V. Πουλάρι

Από το λατινικό recursio (επιστροφή). Σε γενικές γραμμές, αυτό είναι το όνομα που δίνεται στη διαδικασία επανάληψης στοιχείων με «αυτοπαρόμοιο τρόπο».

Ένα εντυπωσιακό παράδειγμα αναδρομής είναι οι κούκλες που φωλιάζουν. Αναδρομικός ορισμός: "μια κούκλα φωλιάς είναι μια αποσπώμενη κούφια ξύλινη κούκλα που περιέχει μια μικρότερη κούκλα μέσα." Αυτό είναι αναδρομή στα ρωσικά. Και αν δεν υπήρχε το όριο των δυνατοτήτων των κυρίων, η ιδανική matryoshka θα έμπαινε βαθιά μέσα της στο ατομικό επίπεδο. Ή ακόμα πιο βαθιά. Ο Lefty απλά δεν είχε ένα μικρό πεδίο, αρκετά δυνατό. Το ανώτερο όριο είναι επίσης θεωρητικά απεριόριστο, αλλά τα μπαομπάμπ κατάλληλου μεγέθους δεν αναπτύσσονται στον πλανήτη μας. Γενικά, για τεχνικούς λόγους, η αναδρομή πρέπει να είναι πεπερασμένη.

Στον προγραμματισμό (όπως στα μαθηματικά), η αναδρομή είναι η διαδικασία μιας συνάρτησης που καλεί τον εαυτό της (άμεση αναδρομή) ή καλεί τη συνάρτηση Β από το εσωτερικό της συνάρτησης Α, η οποία με τη σειρά της περιέχει μια κλήση στη συνάρτηση Α (έμμεση ή αμοιβαία αναδρομή). Φυσικά, οι αναδρομικές κλήσεις πρέπει να έχουν μια ικανοποιητική συνθήκη εξόδου, διαφορετικά το πρόγραμμα θα κολλήσει, όπως σε έναν άπειρο βρόχο - αλλά, σε αντίθεση με έναν άπειρο βρόχο, μια άπειρη αναδρομή θα διακοπεί σε μια υπερχείλιση στοίβας.

Παράδειγμα αναδρομής

Το πιο ενοχλητικό παράδειγμα αναδρομής στον μαθηματικό προγραμματισμό είναι ο υπολογισμός του παραγοντικού. Ας μην αλλάξουμε τις ένδοξες παραδόσεις μας. Για όσους δεν το έχουν πάρει ακόμα: Ν! (παραγοντικό Ν) είναι το γινόμενο όλων των φυσικών αριθμών από το ένα έως το Ν (το παραγοντικό του μηδέν είναι 1).
Μπορείτε να πολλαπλασιάσετε ανόητα αριθμούς από το 1 στο Ν σε έναν βρόχο. Ή μπορείτε να δημιουργήσετε μια συνάρτηση παραγοντική(n), η οποία θα περιέχει μια συνθήκη και μια κλήση στον εαυτό της. Αν το n είναι ίσο με ένα, τότε η συνάρτηση επιστρέφει την τιμή 1, διαφορετικά επιστρέφει την τιμή του n πολλαπλασιασμένη με παραγοντικό(n-1).
Σκίτσο σε PHP

Συνάρτηση παραγοντικό($n) ( αν ($n == 1) ( επιστρέφει 1; ) other ( return intval($n * factorial($n - 1)); ) )

Πρακτικές Εφαρμογές Αναδρομής

«Λοιπόν, γιατί χρειάζεται αυτό εδώ;» - θα μας ρωτήσει ένας ανυπόμονος νεαρός αναγνώστης - «Επιστημονικές ανοησίες, κουραστικότητα, κάθε λογής παραγοντικός... Αλλά πρακτικά, γιατί να εφαρμοστεί αυτή η αναδρομή;»
«Στο μαύρο μάτι του προγραμματισμού Ιστού», θα απαντήσουμε χωρίς δισταγμό. Και θα το δικαιολογήσουμε αμέσως.

Στην πραγματικότητα, υπάρχουν πολύ περισσότερες χρήσεις της αναδρομής στον προγραμματισμό Ιστού από ό,τι φαίνεται. Διότι η αναδρομή είναι, ίσως, ο μόνος τρόπος για να διασχίσουμε οποιαδήποτε δομή δέντρου όταν ούτε το μέγεθός της ούτε το βάθος φωλιάς της είναι γνωστά εκ των προτέρων. Παρεμπιπτόντως, η κατασκευή και η διέλευση γραφημάτων επίσης δεν μπορεί να γίνει χωρίς αυτό. Αυτό είναι ένα κλασικό, κύριοι - προσπαθήστε να αναζητήσετε τα απαραίτητα αρχεία σε ένα δέντρο καταλόγου Unix με κάποιον άλλο τρόπο και θα σας γίνει αμέσως σαφές ότι χωρίς αναδρομή δεν θα φτάσετε πουθενά.

Προσπαθήστε να το κάνετε χωρίς αυτό δημιουργώντας έναν χάρτη τοποθεσίας με μια ιεραρχική δομή ενοτήτων με τη μορφή ένθετων λιστών. Θα προτιμούσατε να κρεμαστείτε παρά να το κατασκευάσετε εάν δεν γνωρίζετε εκ των προτέρων σε πόσα ακριβώς επίπεδα περιορίζεται το βάθος φωλιάς. Και ακόμα κι αν γνωρίζετε, αλλά προσπαθήστε να το κάνετε χωρίς αναδρομή, τότε αντί για μια απλή, διαφανή και ασφαλή λειτουργία, θα δημιουργήσετε ένα δυσκίνητο λογισμικό "ράφι σε πατερίτσες". Και όταν τελειώσετε και σκουπίσετε το ιδρωμένο μέτωπό σας, η ζοφερή αλήθεια της ζωής θα σας ξημερώσει: αν αλλάξετε το βάθος της φωλιάς, η δομή απλώσεώς σας θα σταματήσει αμέσως να λειτουργεί σωστά. Επομένως, είναι απίθανο να μπορείτε να το χρησιμοποιήσετε οπουδήποτε αλλού.

Αναδρομή στις μηχανές αναζήτησης

Ναι ακριβώς. Οι μηχανές αναζήτησης επίσης δεν έχουν πού να ξεφύγουν από την αναδρομή. Δεδομένου ότι καθιερώθηκε το έθιμο να μετράται η αυθεντία ενός ιστότοπου (έγγραφου) με τον αριθμό των συνδέσμων, οι μηχανές αναζήτησης έχουν πέσει σε μια επαναλαμβανόμενη παγίδα και τις αφήνουν να περιπλανώνται σε αυτήν για πάντα (αυτή είναι η ειλικρινής καλή επιθυμία του συγγραφέα). Ο σύνδεσμος "βάρος" ενός ιστότοπου αποτελείται από μικρά κομμάτια "βάρους" από όλα αυτά που συνδέονται με αυτόν. Για να υπολογίσετε αυτό το βάρος για το A, το οποίο αναφέρεται από τα B, C και D, πρέπει να υπολογίσετε το βάρος τους, το οποίο με τη σειρά του μεταδίδεται από κάθε λογής άλλους, το βάρος των οποίων πρέπει επίσης να υπολογιστεί... και ούτω καθεξής σε ολόκληρο το Δίκτυο που λαμβάνεται υπόψη στη μηχανή αναζήτησης. Ένα εντελώς επαναλαμβανόμενο πρόβλημα. Και λες ότι είναι μια πλήρης θεωρία. Η πιο αληθινή πρακτική.

Αναδρομική κατάταξη σελίδας της Google

Οι δημιουργοί της Google δημοσίευσαν τον βασικό τους αλγόριθμο για τον υπολογισμό του PageRank εδώ και πολύ καιρό. Και όσο κι αν έχει αλλάξει από τότε, όσες βελτιώσεις κι αν έχουν προστεθεί σε αυτό, η βάση παραμένει η ίδια. Δεν υπάρχει τρόπος να γνωρίζουμε πόση σελίδα Κατάταξης Β μεταβιβάζει ως σύνδεσμος στη σελίδα Α μέχρι να μετρήσουμε τι έλαβε η σελίδα Β κατάταξης από όλες τις άλλες σελίδες που συνδέθηκαν με αυτήν, και αυτό δεν μπορεί να γίνει γνωστό μέχρι να μετρήσουμε την Κατάταξη σελίδας από αυτές τις σελίδες... θα συνεχίσουμε; Μάλλον δεν χρειάζεται πλέον. Είναι πάλι η Αυτού Μεγαλειότητα Αναδρομή .