Algoritmul Turnului Hanoi: Python, C++ Code
⚡ Rezumat inteligent
Algoritmul Turnului din Hanoi este un puzzle recursiv clasic care mută o stivă de discuri între trei cuie fără a plasa niciodată un disc mai mare peste unul mai mic, ilustrând clar metoda „împarte și cucerește”.

Ce este Turnul din Hanoi?
Turnul Hanoi este un puzzle matematic format din trei tije și o stivă de discuri de dimensiuni descrescătoare, așezate unul peste altul. Este cunoscut și sub numele de Turnul lui Brahma sau turnul Lucas, deoarece matematicianul francez Edouard Lucas l-a introdus în 1883. Puzzle-ul se bazează pe legende despre mutarea discurilor de aur între trei tije.
Acest puzzle are trei tije și un număr variabil de discuri stivuite. Tijele sunt aranjate ca turnuri ciclice, astfel încât discurile mai mari sunt stivuite în partea de jos, iar discurile mai mici sunt stivuite în partea de sus.
Inițial, ni se dau trei cuie sau tije. Una dintre ele (cuiul A în exemplu) are toate discurile stivuite. Scopul este de a muta întreaga stivă de la o tijă (A) la alta (C), respectând câteva reguli specifice.
Iată configurația inițială a puzzle-ului:
Problema Turnului din Hanoi
Și acesta este scopul final:
Regulile Turnului din Hanoi
Iată regulile esențiale pentru Turnul Hanoi:
- În starea inițială a puzzle-ului, toate discurile sunt stivuite pe tija unu.
- În starea finală, toate discurile de la tija unu sunt stivuite pe tija doi sau pe tija trei.
- Doar un disc se poate mișca de la o tijă la alta la un moment dat.
- Doar discul de sus al unei tije poate fi mișcat.
- Un disc nu poate fi plasat peste un disc mai mic.
Legenda originală era despre mutarea a 64 de discuri. Preoții puteau muta câte un disc pe rând, conform regulilor. Conform legendei, exista o profeție conform căreia lumea se va sfârși dacă ar putea finaliza actul. În secțiunea despre complexitatea timpului, vom arăta că o decor de tip Turnul Hanoi cu n discuri necesită 2^n – 1 mutări.
Deci, dacă preoții ar fi avut nevoie de o secundă pentru a muta un disc, timpul total pentru a rezolva puzzle-ul ar fi de 2^64 – 1 secundă, sau aproximativ 584,942,417,356 de ani, 26 de zile, 7 ore și 15 secunde.
Algoritm pentru Turnul din Hanoi
Cea mai comună metodă de a rezolva Turnul Hanoi este un algoritm recursiv. Mai întâi, alegem două tije ca sursă și destinație; cuiul de rezervă acționează ca auxiliar sau ajutor.
Iată pașii pentru a rezolva puzzle-ul Turnul din Hanoi:
- Mutați discurile superioare n-1 de la suportul sursă la suportul de ajutor.
- Mută al n-lea disc de la cuiul sursă la cuiul destinație.
- Mutați cele n-1 discuri rămase de la cuiul ajutor la cuiul destinație.
Notă: Dacă avem un singur disc, îl putem muta direct de la sursă la destinație.
Cum să rezolvi puzzle-ul Turnul din Hanoi
Să ilustrăm algoritmul pentru trei discuri. Considerăm cuiul A ca sursă, cuiul B ca ajutor și cuiul C ca destinație.
Pas 1) Inițial, toate discurile sunt stivuite pe cuiul A.
În această etapă: Sursa = Peg A, Destinația = Peg C, Asistentul = Peg B.
Acum, trebuie să mutăm discurile de sus n-1 de la sursă la helper.
Notă: Deși putem muta doar un disc odată, acest pas reduce problema noastră cu 3 discuri la o problemă cu 2 discuri, care este rezolvată printr-un apel recursiv.
Pas 2) Deoarece efectuăm un apel recursiv de la peg-ul A cu peg-ul B ca destinație, folosim peg-ul C ca ajutor.
Observați că ne-am întors la etapa unu pentru aceeași problemă a Turnului Hanoi, dar acum pentru două discuri. Mutăm n-1 (adică un) disc de la sursă la helper, ceea ce mută cel mai mic disc de la cuiul A la cuiul C.
În această etapă: Sursa = punctul A, Destinația = punctul B, Ajutorul = punctul C.
Pas 3) Conform algoritmului, al n-lea (al doilea) disc este acum transferat la destinație, cuiul B.
În această etapă: Sursa = punctul A, Destinația = punctul B, Ajutorul = punctul C.
Pas 4) Acum, mutăm discul n-1 (discul unu) de la cuiul helper C la cuiul destinație B, urmând a treia etapă a algoritmului.
În această etapă: Sursa = punctul A, Destinația = punctul B, Ajutorul = punctul C.
Pas 5) După finalizarea apelului recursiv, revenim la setările anterioare din prima etapă a algoritmului.
Pas 6) În a doua etapă, mutăm discul 3 de la cuiul sursă A la cuiul destinație C.
În această etapă: Sursa = punctul A, Destinația = punctul C, Ajutorul = punctul B.
Pas 7) Următoarea sarcină este mutarea discurilor rămase de la suport (peg B) la destinație (peg C). De data aceasta vom folosi sursa originală (peg A) ca suport.
Pas 8) Deoarece nu putem muta două discuri simultan, facem un apel recursiv pentru discul 1. Conform instrucțiunilor noastre Algoritmul, destinația în acest pas este cuiul A.
În această etapă: Sursa = punctul B, Destinația = punctul A, Ajutorul = punctul C.
Pas 9) Apelul nostru recursiv este complet. Acum mutăm discul 2 de la sursă la destinație.
În această etapă: Sursa = punctul B, Destinația = punctul C, Ajutorul = punctul A.
Pas 10) Terminăm prin mutarea discului n-1 rămas (discul 1) de la helper la destinație.
În această etapă: Sursa = punctul A, Destinația = punctul C, Ajutorul = punctul B.
Pseudo Code pentru Turnul Hanoi
START
Procedure Tower_Of_Hanoi(disk, source, dest, helper)
IF disk == 1 THEN
move disk from source to dest
ELSE
Tower_Of_Hanoi(disk - 1, source, helper, dest)
move disk from source to dest
Tower_Of_Hanoi(disk - 1, helper, dest, source)
END IF
END Procedure
Codul programului în C++
#include <bits/stdc++.h> using namespace std; void tower_of_hanoi(int num, string source, string dest, string helper) { if (num == 1) { cout << " Move disk 1 from tower " << source << " to tower " << dest << endl; return; } tower_of_hanoi(num - 1, source, helper, dest); cout << " Move disk " << num << " from tower " << source << " to tower " << dest << endl; tower_of_hanoi(num - 1, helper, dest, source); } int main() { int num; cin >> num; printf("The sequence of moves :\n"); tower_of_hanoi(num, "I", "III", "II"); return 0; }
ieșire:
3 The sequence of moves : Move disk 1 from tower I to tower III Move disk 2 from tower I to tower II Move disk 1 from tower III to tower II Move disk 3 from tower I to tower III Move disk 1 from tower II to tower I Move disk 2 from tower II to tower III Move disk 1 from tower I to tower III
Codul programului în Python
def tower_of_hanoi(n, source, destination, helper): if n == 1: print("Move disk 1 from peg", source, "to peg", destination) return tower_of_hanoi(n - 1, source, helper, destination) print("Move disk", n, "from peg", source, "to peg", destination) tower_of_hanoi(n - 1, helper, destination, source) # n = number of disks n = 3 tower_of_hanoi(n, 'A', 'B', 'C')
ieșire:
Move disk 1 from peg A to peg B Move disk 2 from peg A to peg C Move disk 1 from peg B to peg C Move disk 3 from peg A to peg B Move disk 1 from peg C to peg A Move disk 2 from peg C to peg B Move disk 1 from peg A to peg B
Complexitatea Turnului din Hanoi
Iată complexitatea temporală și spațială a Turnului Hanoi:
1) Complexitatea timpului:
Privind retrospectiv la algoritm, facem un apel recursiv pentru (n-1) discuri de două ori per apel. Fiecare recursiune (n-1) se descompune în ((n-1)-1) recursii și așa mai departe, până când ajungem la cazul de bază cu un singur disc.
Pentru trei discuri:
- Discul 3 apelează funcția recursivă pentru discul 2 de două ori.
- Discul 2 apelează funcția recursivă pentru discul 1 de două ori.
- Discul 1 se mișcă în timp constant, oferind timpul necesar pentru a rezolva pentru trei discuri.
Exprimată ca recurență:
= 2 × (Timpul necesar pentru rezolvarea a două discuri) + timpul constant necesar pentru mutarea discului 3
= 2 × (2 × timpul necesar pentru rezolvarea unui disc + timpul constant necesar pentru mutarea discului 2) + timpul constant necesar pentru mutarea discului 3
= (2 × 2) × timpul constant pentru mutarea discului 1 + 2 × timpul constant pentru mutarea discului 2 + timpul constant pentru mutarea discului 3
Pentru n discuri, aceasta devine:
2n-1 × timp constant pentru a muta discul 1 + 2n-2 × timpul constant necesar pentru mutarea discului 2 + ….
Această progresie geometrică se însumează cu O(2n – 1), ceea ce simplifică la O(2n), o complexitate temporală exponențială.
2) Complexitatea spațiului:
Complexitatea spațială a Turnului Hanoi este O(n). Recursivitatea folosește stiva de apeluri, iar adâncimea maximă a stivei este egală cu n, numărul de discuri. De aceea, complexitatea spațială este O(n).










