I_R_W14_M42_C++ Ciekawe algorytmy rekurencyjne
Implementacja rozwiązania w języku C++
Zagadkę Wież Hanoi dla n krążków rozwiążemy w sposób rekurencyjnyrekurencyjny. Program przetestujemy dla trzech krążków.
Specyfikacja:
Dane:
n– liczba krążków; liczba naturalna dodatniaA– nazwa słupka początkowego; znakB– nazwa słupka pomocniczego; znakC– nazwa słupka docelowego; znak
Wynik:
Program na standardowym wyjściu wypisuje ciąg ruchów opisujący rozwiązanie zagadki wież Hanoi dla n krążków, gdzie początkowo wszystkie znajdują się na słupku A. Na końcu wszystkie krążki mają znaleźć się na słupku C, a pomocniczym słupkiem jest B.
Tworzymy funkcję o nazwie hanoi(), której przyjmowanymi parametrami wejściowymi będzie n, czyli liczba krążków, a następnie A, B, C, czyli nazwy słupków: początkowego, pomocniczego, a także końcowego.
Następnie, gdy liczba krążków jest większa od 0 (dla liczby krążków równej 0 zajdzie przypadek bazowyprzypadek bazowy), możemy wykonywać algorytm. Wywołamy na początku rekurencyjnie funkcję hanoi, która zrealizuje przeniesienie n - 1 górnych krążków ze słupka A na słupek B. Na słupku A pozostanie tylko jeden, n-ty, największy krążek. Reszta krążków będzie nałożona na słupek B.
Operację przeniesienia n - 1 górnych krążków ze słupka A na słupek B przedstawia ilustracja:

Największy krążek musi zostać przełożony na słupek docelowy C. Wypisujemy zatem na ekran komunikat: „Przeniesienie z” A „do” C.
Operację przeniesienia n-tego krążka na słupek docelowy C, przedstawia rysunek:

Na koniec musimy jeszcze wywołać rekurencyjnie funkcję hanoi, aby przenieść n - 1 krążków ze słupka B na słupek C, na którym położony jest już największy krążek.
Aby to zrealizować, pierwszym przyjmowanym argumentem będzie n - 1, ponieważ chcemy przenieść właśnie taką liczbę krążków. Drugim argumentem będzie B, ponieważ tym razem ten słupek jest słupkiem początkowym. Następnie umieszczamy A, ponieważ w tej sytuacji będzie on słupkiem pomocniczym, a na końcu słupek docelowy C.

Teraz wystarczy wywołać funkcję hanoi, np. dla trzech krążków z nazwami słupków: A, B, C.
Ciąg ruchów otrzymany w wyniku wywołania funkcji dla trzech krążków będzie wyglądał następująco:
Przeniesienie z A do C
Przeniesienie z A do B
Przeniesienie z C do B
Przeniesienie z A do C
Przeniesienie z B do A
Przeniesienie z B do C
Przeniesienie z A do C
Zobaczmy jeszcze, jak będzie wyglądało drzewo wywołań rekurencyjnych dla wywołania funkcji hanoi(3, 'A', 'B', 'C'). Dzięki niemu, będziemy mogli zobaczyć wszystkie wywołania funkcji hanoi. Lewa strzałka odchodząca od danej funkcji, będzie wskazywała na pierwsze wywołanie funkcji, umieszczone w szóstej linijce naszego kodu, natomiast prawa strzałka wskaże nam drugie wywołanie, z ósmej linijki. Aby odczytać rozwiązanie problemu z drzewa wywołań rekurencyjnych, najpierw musimy odczytać ruchy z lewego poddrzewa węzła, następnie ruch należący do węzła – ojca, a na końcu ruchy z prawego poddrzewa.

Zagadka wież Hanoi jest przykładem zadania, którego złożność obliczeniowa wzrasta bardzo szybko wraz z liczbą krążków n. Przedstawiony algorytm ma złożoność wykładnicząwykładniczą, to znaczy .
Słownik
algorytm, w którym funkcja lub procedura wywołuje samą siebie; parametry wywołania takiej funkcji lub procedury rekurencyjnej mogą się zmieniać; odwołania rekurencyjnie pozostawiają na stosie systemowym adres i parametry powrotu do danej funkcji lub procedury
problem, polegający na przeniesieniu wieży z krążków z jednego słupka na drugi, przy czym można przenosić tylko po jednym krążku z wierzchu stosu; nie jest dozwolone położenie większego krążka na mniejszym
warunek w funkcji rekurencyjnej, po spełnieniu którego funkcja nie wywołuje samej siebie po raz kolejny
złożoność, która jest określona za pomocą funkcji wykładniczej, rośnie wykładniczo w zależności od rozmiaru danych wejściowych n