- Αρμονική Σειρά (sumSeries) — Μαθηματικός ορισμός, κώδικας C, φάσεις κάθοδου/ανόδου, animated στοίβα κλήσεων για
sumSeries(4) - Αλγόριθμος Ευκλείδη (ΜΚΔ/GCD) — Αναδρομικός ορισμός, κώδικας C, πίνακας mod, animated στοίβα κλήσεων για
gcd(48, 18)
Η Αρμονική Σειρά αναδρομικά
Η αρμονική σειρά είναι ένα κλασικό παράδειγμα αναδρομής: υπολογίζουμε το άθροισμα
S(n) = 1/1 + 1/2 + 1/3 + ... + 1/n. Ο αναδρομικός ορισμός λέει ότι
το άθροισμα μέχρι το n ισούται με 1/n συν το άθροισμα μέχρι
το n-1. Βασική περίπτωση: όταν n == 1, το αποτέλεσμα
είναι 1.0.
double και όχι int;
Επειδή τα 1/n δίνουν δεκαδικά αποτελέσματα (π.χ. 1/3 = 0.333…).
Αν χρησιμοποιούσαμε int, θα είχαμε ακέραια διαίρεση
(1/2 = 0, 1/3 = 0…) και θα χάναμε όλη την ακρίβεια!
Γι' αυτό γράφουμε 1.0 / n (double διαίρεση).
Κώδικας σε C
Βήμα-Βήμα: Φάσεις Κάθοδου & Ανόδου
Η εκτέλεση της sumSeries(4) ακολουθεί το γνωστό μοτίβο δύο φάσεων:
📉 ΚΑΘΟΔΟΣ (Κλήσεις)
sumSeries(4) → χρειάζεται sumSeries(3)
sumSeries(3) → χρειάζεται sumSeries(2)
sumSeries(2) → χρειάζεται sumSeries(1)
sumSeries(1) → ΒΑΣΗ! Επιστρέφει 1.0
📈 ΑΝΟΔΟΣ (Επιστροφές)
sumSeries(1) = 1.0
sumSeries(2) = 1/2 + 1.0 = 1.5
sumSeries(3) = 1/3 + 1.5 = 1.8333
sumSeries(4) = 1/4 + 1.8333 = 2.0833
Animated Βήμα-Βήμα: sumSeries(4)
Χρησιμοποιήστε τα κουμπιά για να δείτε ακριβώς πώς χτίζεται και αποχτίζεται η στοίβα κλήσεων:
Τι Αποθηκεύεται στη Στοίβα;
Κάθε κλήση της sumSeries δημιουργεί ένα νέο πλαίσιο στοίβας (stack frame):
- Η τιμή της παραμέτρου
n(π.χ. n=4, n=3, …) - Η διεύθυνση επιστροφής — πού θα συνεχίσει ο κώδικας όταν τελειώσει
- Το ενδιάμεσο αποτέλεσμα
1.0/nπεριμένει τη συνέχεια
factorial που πολλαπλασιάζει, η sumSeries προσθέτει δεκαδικά κλάσματα. Γι' αυτό χρησιμοποιούμε τύπο double (και γράφουμε 1.0 / n αντί 1 / n).
Αλγόριθμος Ευκλείδη — Μέγιστος Κοινός Διαιρέτης (ΜΚΔ)
Ο Μέγιστος Κοινός Διαιρέτης (ΜΚΔ) δύο αριθμών α και β μπορεί να υπολογιστεί αναδρομικά με τον αλγόριθμο του Ευκλείδη — έναν αλγόριθμο ηλικίας 2.300+ ετών που είναι ίσως ο αρχαιότερος αλγόριθμος στην ιστορία!
β θα γίνει 0, και τότε ο ΜΚΔ είναι ο α.
Τι σημαίνει α mod β;
Ο τελεστής % (modulo) επιστρέφει το υπόλοιπο της ακέραιας διαίρεσης:
| Πράξη | Πηλίκο | Υπόλοιπο (mod) |
|---|---|---|
| 48 ÷ 18 | 2 | 48 % 18 = 12 |
| 18 ÷ 12 | 1 | 18 % 12 = 6 |
| 12 ÷ 6 | 2 | 12 % 6 = 0 |
ΜΚΔ — Κώδικας σε C
a γίνεται b και το b γίνεται a%b. Η σύγκλιση στη βάση (b == 0) εξασφαλίζεται γιατί το υπόλοιπο πάντα μικραίνει.
ΜΚΔ — Φάσεις Κάθοδου & Ανόδου
Η εκτέλεση της gcd(48, 18) ακολουθεί δύο φάσεις — αλλά εδώ η «άνοδος» είναι πιο απλή, γιατί δεν γίνεται πράξη μετά την αναδρομική κλήση. Η τιμή απλά «περνά» πίσω:
📉 ΚΑΘΟΔΟΣ (Κλήσεις)
gcd(48, 18) → 48%18=12 → καλεί gcd(18, 12)
gcd(18, 12) → 18%12=6 → καλεί gcd(12, 6)
gcd(12, 6) → 12%6=0 → καλεί gcd(6, 0)
gcd(6, 0) → b==0, ΒΑΣΗ! Επιστρέφει 6
📈 ΑΝΟΔΟΣ (Επιστροφές)
gcd(6, 0) = 6 ← βασική
gcd(12, 6) = 6 ← περνά πίσω
gcd(18, 12) = 6 ← περνά πίσω
gcd(48, 18) = 6 ← τελικό!
return gcd(b, a%b) είναι η τελευταία πράξη — δεν γίνεται πρόσθεση ή πολλαπλασιασμός μετά. Αυτό λέγεται tail recursion και θεωρητικά μπορεί να βελτιστοποιηθεί από τον compiler!
Animated Βήμα-Βήμα: gcd(48, 18)
Χρησιμοποιήστε τα κουμπιά για να δείτε ακριβώς πώς χτίζεται και αποχτίζεται η στοίβα κλήσεων:
ΜΚΔ — Τι Αποθηκεύεται στη Στοίβα;
Κάθε κλήση της gcd δημιουργεί ένα νέο πλαίσιο στοίβας με τις τρέχουσες τιμές a και b: