Algorytmika dla początkujących Uniwersytet Marii Curie-Skłodowskiej Wydział Matematyki, Fizyki i Informatyki Instytut Informatyki Algorytmika dla początkujących Jacek Krzaczkowski Lublin 2012 Instytut Informatyki UMCS Lublin 2012 Jacek Krzaczkowski Algorytmika dla początkujących Recenzent: Grzegorz Matecki Opracowanie techniczne: Marcin Denkowski Projekt okładki: Agnieszka Kuśmierska Praca współfinansowana ze środków Unii Europejskiej w ramach Europejskiego Funduszu Społecznego Publikacja bezpłatna dostępna on-line na stronach Instytutu Informatyki UMCS: informatyka.umcs.lublin.pl. Wydawca Uniwersytet Marii Curie-Skłodowskiej w Lublinie Instytut Informatyki pl. Marii Curie-Skłodowskiej 1, 20-031 Lublin Redaktor serii: prof. dr hab. Paweł Mikołajczak www: informatyka.umcs.lublin.pl email: [email protected] Druk FIGARO Group Sp. z o.o. z siedziba w Rykach ul. Warszawska 10 08-500 Ryki www: www.figaro.pl ISBN: 978-83-62773-36-7 Spis treści Przedmowa vii 1 Na dobry początek 1 1.1. Zanim zaczniemy implementować algorytmy . . . . . . . . . . 2 1.2. Elementy teorii złożoności . . . . . . . . . . . . . . . . . . . . 6 2 Struktury danych, abstrakcyjne typy danych, listy 11 2.1. Abstrakcyjne typy danych . . . . . . . . . . . . . . . . . . . . 12 2.2. Listy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.3. Proste algorytmy sortujące . . . . . . . . . . . . . . . . . . . 35 2.4. Kolejka, stos, kolejka priorytetowa . . . . . . . . . . . . . . . 48 3 Przeszukiwanie wyczerpujące 57 3.1. Przeszukiwanie wszystkich możliwości . . . . . . . . . . . . . 58 3.2. Przeszukiwanie z nawrotami . . . . . . . . . . . . . . . . . . . 72 4 Metoda dziel i zwyciężaj 77 4.1. O metodzie . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 4.2. Zmniejsz i zwyciężaj . . . . . . . . . . . . . . . . . . . . . . . 90 5 Programowanie dynamiczne 97 5.1. O metodzie . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 5.2. Metoda spamiętywania . . . . . . . . . . . . . . . . . . . . . . 116 6 Algorytmy zachłanne 121 6.1. O metodzie . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 6.2. Przykłady . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 7 Drzewa 131 7.1. Definicja drzew i sposoby ich reprezentacji . . . . . . . . . . . 132 7.2. Przechodzenie drzew . . . . . . . . . . . . . . . . . . . . . . . 135 7.3. Kopce, sortowanie przez kopcowanie . . . . . . . . . . . . . . 138 8 Grafy 151 vi SPIS TREŚCI 8.1. Definicja i sposoby reprezentacji grafu . . . . . . . . . . . . . 152 8.2. Przechodzenie grafów. . . . . . . . . . . . . . . . . . . . . . . 156 Bibliografia 161 Przedmowa viii Przedmowa Algorytmikaiprogramowanietopodstawyinformatyki.Beznichtrudno mówić o korzystaniu z komputerów i o informatyce w ogóle. Nie na darmo David Harel nadał swojej znanej książce tytuł „Rzecz o istocie informatyki. Algorytmika”[3]. Biorąc to pod uwagę zaskakująco często programowanie, a szczególnie implementacja mniej lub bardziej zaawansowanych algoryt- mów, sprawia dużą trudność wielu studentom informatyki. Najpopularniej- szepodręcznikidoalgorytmikizakładają,żeichczytelnikomprogramowanie nie sprawia problemu. Stąd, dla studentów, którzy nie nauczyli się jeszcze dobrze programować, a już muszą próbować implementować proste algoryt- my, podręczniki te często nie są zbyt użyteczne. W odróżnieniu od wspo- mnianych podręczników, książka, którą Czytelniku trzymasz w ręku, pró- buje uczyć podstaw algorytmiki i programowania jednocześnie. Na ile jest to próba udana, ocenisz sam. Niniejszy skrypt nie jest klasycznym wykładem z algorytmiki. Jest on raczej pomyślany jako uzupełnienie podstawowego wykładu z algorytmiki przeznaczone przede wszystkim dla tych studentów, którzy nie radzą so- bie z implementowaniem prostych algorytmów. Bardziej zaawansowanych czytelników mogą nużyć długie opisy kolejnych kroków implementacji pro- stych funkcji, ale mają one pomóc początkującemu czytelnikowi zrozumieć nie tylko ideę algorytmu, ale także to, jak go zaimplementować. Nieprzy- padkowy jest także dobór materiału do książki. Skupiono się na najprost- szychstrukturachdanychipodstawowychmetodachkonstruowaniaalgoryt- mów. Wszystko to z myślą o czytelnikach, którzy, aby móc implementować bardziej skomplikowane algorytmy, muszą jeszcze popracować nad swoimi umiejętnościami programistycznymi. Stąd rozdział o listach i prostych algo- rytmachnanichjestznaczniedłuższyodrozdziałówodrzewachczygrafach. Programowanie to przede wszystkim praktyka. Nie da się nauczyć pro- gramować wyłącznie czytając książki. Tak samo pisanie programów i nie- kompilowanie ich albo kompilowanie i nieuruchamianie nie pozwoli nauczyć się programowania. Na końcu poszczególnych rozdziałów czytelnik znajdzie proste zadania dotyczące omawianych zagadnień. Warto spróbować je za- implementować i przetestować ich działanie. Ponadto wszystkie algorytmy przedstawione w książce zostały zaimplementowane w języku C++ w ta- ki sposób, aby nadawały się do przekopiowania i użycia po minimalnych zmianach w programach czytelników. Warto spróbować samodzielnie zaim- plementować omawiane algorytmy, a w razie problemów porównywać swój kod z tym zamieszczonym w książce. Czytelnik, który zechce poszerzyć w swoją wiedzę w zakresie algorytmi- ki, może sięgnąć po którąś z pozycji wymienionych w bibliografii. Szczegól- nie godne polecenia są dostępne bezpłatnie w internecie kursy na stronie Studiów Informatycznych [7]. Ci, którzy wolą obcować z papierową książką, przedewszystkimmogąskorzystaćz[2],atakżez[1]i[4].Jeżelikogośzainte- Przedmowa ix resuje generowanie obiektów kombinatorycznych prezentowane w rozdziale 3.1, może sięgnąć po [5], zaś zainteresowani zgłębianiem teorii złożoności po [6].