W celu zrozumienia na czym polega Sortowanie Naleśnikowe należy przyjrzeć się procesowi smażenia naleśników. Zazwyczaj każdego robi się oddzielnie wypełniając masą całą powierzchnię patelni tak, aby były jak największe. Oznacza to jednak, że po przygotowaniu naleśnik trafia na pewien stos, aż wszystkie naleśniki zostaną zrobione. Pomimo szczerych chęci naleśniki nie zawsze wychodzą takiego samego rozmiaru.
W celu posortowania naleśników tak, aby na dole były największe, a u góry największe można posłużyć się łopatką. W tym celu wybieramy naleśnik pod który podkładamy łopatkę, a następnie obracamy cały stos na łopatce do góry nogami. Kontynuując ten proces dochodzimy do momentu, gdy stos zostanie posortowany. Jednak jak się zabrać za tego typu sortowanie?
Rozpocznijmy od najprostszych przypadków. Jednego naleśnika nie ma co sortować, a w przypadku dwóch wystarczy odwrócić kolejność. Problem jednak się zaczyna dla trzech. Jeśli największy naleśnik jest na wierzchu to wystarczy odwrócić stos i znajdzie się na dole, a pozostałe dwa ewentualnie ponownie obrócić. Jednak jeśli nie znajduje się na wierzchu to można odwrócić fragment stosu tak, aby się na wierzchu znalazł.
Zasadę tę można przenieść na stosy o większej ilości naleśników. Po ułożeniu największego naleśnika na dole można rozpatrywać sortowanie stosu o jeden element mniejszego. Warto tutaj zauważyć, że implementacja rekurencyjnego sortowania będzie pasować idealnie.
Poniżej został przedstawiony problem sortowania naleśników ułożonych na stosie (od dołu) kolejno: 3, 4, 1, 2. Najpierw znajdujemy największy naleśnik i przerzucamy go na górę stosu.
Teraz bardzo łatwo można go przerzucić na dół stosu - wystarczy obrócić cały stos do góry nogami. W tym celu wkładamy łopatkę pod cały stos.
Największy naleśnik jest już na miejscu, więc rozpatrujemy stos o jeden naleśnik mniejszy. Największy z nich leży na wierzchu, więc wkładamy szpatułkę nad ustawiony wcześniej element.
Stos został posortowany. Program jeszcze by dodatkowo posortował dwa naleśniki z wierzchu (tj. tylko sprawdził czy są posortowane).
Co można przedstawić schematycznie w postaci tabeli:
Stos | Operacja |
---|---|
3, 4, 1, 2 | Odwracamy od pozycji 2 |
3, 2, 1, 4 | Odwracamy od początku |
4, 1, 2, 3 | Odwracamy od pozycji 2 |
4, 3, 2, 1 | Stos posortowany (program jeszcze wykonałby porównania) |
W celu zaimplementowanie tego algorytmu potrzebne są funkcje do: wyszukiwania elementu maksymalnego oraz do obracania wszystkich elementów począwszy od pewnego indeksu.
Funkcja wyszukajMaksimum() wyszukuje w pewnej tablicy tab o długości n największą wartość od indeksu i. Funkcja zwraca pozycję takiego elementu.
Warto zauważyć, że w celu odwrócenia n elementów trzeba wykonać maksymalnie n/2 zamian, ponieważ za każdym razem zmieniamy wartości na skraju i zwężamy przedział o jeden z każdej strony.
Taką funkcjonalność implementuje funkcja odwroc(), która odwraca w tablicy tab o długości n elementy od indeksu i do ostatniego.
Funkcja sortowanieNalesnikowe() przyjmuje do posortwania tablicę tab o n elementach.
(2.) Pomijamy przypadek trywialny, a następnie (3.) w pętli do posortowania n - 1 elementów w każdej iteracji (4.) wyszukujemy elementu największego. Jeśli (5.) największy naleśnik nie leży na wierzchu to (6.) ustaw go tam, a następnie (7.) przestaw go na dół stosu.
Program można przetestować poniższym fragmentem kodu:
Napisz program, który będzie sortował naleśniki tak, aby namniejszy znalazł się na dole stosu. Uwaga: nie wolno na koniec sortowania odwrócić całego stosu, aby posortować malejąco.
Przykładowo dla stosu (od dołu): {5, 3, 1, 2, 4} program powinien zwrócić: