Algorytmy sortowania Przez sortowanie rozumiemy porz dkowanie elementów tablicy; takie jej przekształcenie, aby jej elementy układały si w zale no ci od potrzeb rosn co lub malej co. a) sortowanie b belkowe W tej metodzie w ka dym obiegu p tli wewn trznej przebiegamy przez wszystkie elementy tablicy porównuj c ka dy z nich z elementem po nim nast puj cym. Je eli dane dwa elementy nie zachowuj okre lonego porz dku (np. gdy chcemy posortowa tablic rosn co, a pierwszy jest wi kszy ni drugi) zamieniamy je miejscami. P tla zewn trzna wykonuje si tak długo, dopóki w p tli wewn trznej wyst pi przynajmniej jedna zamiana. Nazwa pochodzi od faktu, e skrajne elementy okre lonego porz dku (np. w sortowaniu rosn cym element najwi kszy, w malej cym najmniejszy) w druj kolejno na koniec tablicy, tak jak p cherzyki powietrza w wodzie unosz si do góry. Przykład Posortuj metod b belkow zbiór pi ciu elementów: 9 5 6 3 1 w porz dku rosn cym. Funkcja porównuj ca przyjmuje posta : ( a, b) a b Rozpisany pierwszy obieg sortowania: f p 9 5 6 3 1 Porównujemy pierwszy element z drugim. 9>5, zatem elementy zamieniamy miejscami. 1 obieg 5 9 6 3 1 Przesuwamy si do nast pnego elementu i porównujemy go z s siadem. 9>6 zamieniamy je miejscami. 5 6 9 3 1 9>3 zamieniamy miejscami. 5 6 3 9 1 9>1 zamieniamy miejscami. 5 6 3 1 9 Koniec pierwszego obiegu sortowania. Zbiór nadal jest nieposortowany. W celu posortowania całego zbioru naley wykona 5 obiegów porzdkujcych, w których 20 razy porównuje si elementy i dokonuje 9 zamian. Po wykonaniu pierwszego obiegu maksymalny element zbioru został umieszczony na samym kocu, czyli wypłynł jak bbelek powietrza na powierzchni wody. Zatem w drugim obiegu nie ma sensu sprawdza, czy element ten jest na właciwej pozycji, gdy on jest na właciwej pozycji. Podobnie w obiegu drugim, kolejny najwikszy element zostaje umieszczony na swojej docelowej pozycji. W nastpnych obiegach jest identycznie. Podstawy Informatyki 2 rok akad. 2003/2004 mgr in. Paweł Myszkowski 1
Wniosek: w sortowaniu b belkowym kolejne obiegi umieszczaj na wła ciwych miejscach w porz dkowanym zbiorze kolejne elementy maksymalne. Algorytm sortowania b belkowego 1. Je li liczba elementów w zbiorze jest mniejsza od 2, ko czymy algorytm. 2. Rozpoczynamy od pierwszego elementu. 3. Bie cy element porównujemy z elementem bezpo rednio nast pnym w zbiorze. Je li kolejno elementów jest zła, to zamieniamy je miejscami. 4. Je li bie cy element nie jest przedostatnim elementem zbioru, to przesuwamy si do kolejnego elementu i wracamy do punktu 3. 5. Je li w trakcie przegl dania zbioru dokonali my zamiany miejsc elementów, wracamy si do punktu 2. 6. Koniec. Oznaczenia: D zbiór elementów do posortowania n liczba elementów w zbiorze D zamiana zmienna logiczna okre laj ca, czy w danym obiegu sortuj cym zamieniano miejscami jakie elementy zbioru D i indeks przegl danych elementów f p () funkcja porównuj ca x zmienna pomocnicza, wykorzystywana przy wymianie zawarto ci elementów d i i-ty element zbioru D Podstawy Informatyki 2 rok akad. 2003/2004 mgr in. Paweł Myszkowski 2
Zamiana zawarto ci dwóch elementów W algorytmie wykorzystywana jest operacja wymiany dwóch elementów. Operacj tak wykonujemy zawsze w trzech krokach korzystaj c z dodatkowego elementu pomocniczego: temp A A B B temp b) sortowanie przez wstawianie Algorytm sortowania przez wstawianie w porównaniu do opisanego wcze niej algorytmu sortowania b belkowego jest du o szybszy i bardziej efektywny, lecz oczywi cie bardziej zło ony koncepcyjnie. Zasada działania tego algorytmu przypomina układanie w r ce kart pobieranych kolejno z talii. Przykład 1 obieg 9 5 6 3 1 3 9 5 6 1 s 3 9 5 6 1 9 5 6 1 3 9 5 6 1 3 Na ko cu zbioru tworzymy tzw. list uporzdkowanych elementów. Pocztkowo lista ta zawiera tylko jeden, ostatni element zbioru. Ze zbioru wycigamy element lecy bezporednio przed list uporzdkowan. Tutaj jest to liczba 3. Zajmowane przez ni miejsce w zbiorze staje si wolne. Wycigni ty element porównujemy kolejno z elementami listy, a napotkamy jej koniec lub element wi kszy lub równy. Poniewa element listy jest mniejszy od biecego elementu, przesuwamy go w zbiorze na zwolnione miejsce. Puste miejsce przemieszcza si wg łb listy uporzdkowanej. Na licie uporzdkowanej nie ma wi cej elementów do porównania. Zatem element biecy umieszczamy w zbiorze na wolnym miejscu. Zwró uwag, i przemiecił si on w stosunku do swojej pozycji pierwotnej, a na ko cu zbioru powstała dwuelementowa lista uporzdkowana. Podstawy Informatyki 2 rok akad. 2003/2004 mgr in. Paweł Myszkowski 3
W celu posortowania trzeba wykona 4 obiegi, w których trzeba dokona 10 porówna i 9 przesuni elementów zbioru. Algorytm sortowania przez wstawianie 1. Jeli zbiór zawiera mniej ni dwa elementy, to ko czymy. 2. Na ko cu zbioru tworzymy list uporzdkowanych elementów. Pocztkowo lista ta obejmuje jeden, ostatni element. 3. Sortowanie rozpoczynamy od elementu lecego w zbiorze tu przed list uporzdkowan. Element wycigamy ze zbioru. Miejsce zajmowane przez niego staje si wolne. 4. Wycigni ty element porównujemy kolejno z elementami na licie uporzdkowanej. Jeli element listy jest mniejszy (ze wzgl du na porzdek wyznaczony przez funkcj porównujc) od elementu wycigni tego, to przesuwamy go na wolne miejsce. Operacj t powtarzamy dotd, a napotkamy koniec listy lub element wi kszy lub równy elementowi wycigni temu. 5. Element wycigni ty wstawiamy na wolne miejsce. Rozmiar listy uporzdkowanej ronie o 1 element. 6. Jeli lista uporzdkowana nie obejmuje jeszcze całego zbioru, to przechodzimy do punktu 2. 7. W przeciwnym wypadku ko czymy algorytm. Oznaczenia: D zbiór do posortowania n liczba elementów w zbiorze D i, j zmienne licznikowe p tli x zmienna pomocnicza przechowujca wybrany element d i i-ty element zbioru D f p ( ) funkcja porównuj ca dwa elementy zbioru D Podstawy Informatyki 2 rok akad. 2003/2004 mgr in. Paweł Myszkowski 4
c) sortowanie przez wybór Algorytm 1. Jeli zbiór liczy mniej ni dwa elementy, to ko czymy. 2. W zbiorze wyszukujemy najmniejszy element. 3. Najmniejszy element zamieniamy miejscami z pierwszym elementem zbioru. 4. Za nowy zbiór przyjmujemy zbiór bez pierwszego elementu, gdy ten jest ju na prawidłowym miejscu. Powracamy do punktu 1. Przykład Naley posortowa zbiór: 9 5 6 3 1 w porzdku rosncym. Funkcja porównujca przyjmie zatem posta: f p ( a, b) a b 9 5 6 3 1 1 5 6 3 9 Znajdujemy najmniejszy element w zbiorze. Jest nim liczba 1. Element ten wymieniamy z pierwszym elementem zbioru. Element ten jest ju na swojej właciwej pozycji. Za nowy zbiór przyjmujemy zbiór bez pierwszego elementu 1 5 6 3 9 Znajdujemy najmniejszy element liczb 3. 1 3 6 5 9 Wymieniamy z pierwszym elementem nowego zbioru. 1 3 6 5 9 Znajdujemy najmniejszy element. 1 3 5 6 9 Wymieniamy go z pierwszym. 1 3 5 6 9 Znajdujemy najmniejszy element. 1 3 5 6 9 Wymieniamy z pierwszym elementem (z samym sob) 1 3 5 6 9 Zbiór jednoelementowy elementy pierwotnego zbioru zostały uporzdkowane. Wyszukanie najmniejszego elementu w zbiorze Algorytm 1. Tymczasowy najmniejszy (najwi kszy) element przyjmujemy pierwszy element zbioru. Podstawy Informatyki 2 rok akad. 2003/2004 mgr in. Paweł Myszkowski 5
2. Jeli zbiór ma mniej ni dwa elementy, ko czymy. 3. Za pomoc funkcji porównujcej sprawdzamy kolejno element tymczasowy z pozostałymi elementami zbioru. Jeli w wyniku porównania elementu tymczasowego z elementem zbioru funkcja porównujca da wynik false (dla elementu najwi kszego da wynik true), to za nowy element najmniejszy (najwi kszy) przyjmujemy dany element zbioru i kontynuujemy przegldanie. Przykład Znale najmniejszy element w zbiorze 4 7 3 2 5 1 w porzdku rosncym. 4 4 7 3 2 5 1 Za tymczasowy element najmniejszy przyjmujemy pierwszy element zbioru, czyli liczb 4. 4 4 7 3 2 5 1 f p(4, 7) = true przechodzimy do nast pnego elementu 4 4 7 3 2 5 1 f p(4,3) = false zast pujemy 4 liczb 3, itd. D sortowany zbiór n liczba elementów w zbiorze D i, j zmienne licznikowe p tli m przechowuje indeks elementu minimalnego f p ( ) funkcja porównujca dwa elementy ze zbioru D x zmienna pomocnicza, uywana przy wymianie zawartoci elementów d i i-ty element zbioru D Podstawy Informatyki 2 rok akad. 2003/2004 mgr in. Paweł Myszkowski 6
d) szybkie sortowanie - quicksort Sortowanie QuickSort zostało wynalezione przez C.A.R. Hoare'a. Jest to jeden z najpopularniejszych algorytmów sortowania. Wpłyn ły na to dwie rzeczy. Po pierwsze jest ono bardzo szybkie (jak sama nazwa wskazuje), a po drugie - proste do wytłumaczenia i implementacji. W praktyce jest to najszybszy algorytm sortowania du ych tablic danych. Sortowanie szybkie opiera si na technice "dziel i zwyci aj". Wej ciowa tablica jest dzielona (po przestawieniu niektórych z jej elementów) na dwie mniejsze. Ka dy element pierwszej tablicy nie jest wi kszy ni ka dy element drugiej tablicy. Liczb, według której wykonuje si podziału to najcz ciej pierwszy element tablicy. Nast pnie dla tych dwóch podtablic wywoływany jest rekurencyjnie ten sam algorytm. Wywołania rekurencyjne ko cz si a która z kolejnych podtablic b dzie zawierała tylko jeden element. Posortujmy dla przykładu nast puj c tablic : 5 7 8 1 4 0 4 6 8 2 1 5 2 6 9 Liczb, według której b dziemy wykonywa podział b dzie pierwsza liczba danej tablicy - w tym przypadku jest to 5. Na pocz tku przegl damy tablic od lewej strony, a znajdziemy element wi kszy od naszej liczby. W tym przypadku jest to element drugi, czyli 7. Nast pnie przegl damy nasz tablic od ko ca a znajdziemy element mniejszy od naszej liczby (5). Tym elementem jest trzeci od ko ca, czyli liczba 2. 5 7 8 1 4 0 4 6 8 2 1 5 2 6 9 Elementy, które ju "przeszli my" s pogrubione, a te, na których zatrzymali my si podkre lone. Tak wi c po lewej stronie zatrzymali my si na 7, a po prawej na 2. Teraz zamieniamy te elementy ze sob : 5 2 8 1 4 0 4 6 8 2 1 5 7 6 9 Znowu kontynuujemy przegl danie od lewej strony. Zatrzymujemy si na elemencie trzecim, czyli 8. A w przegl daniu od ko ca zatrzymujemy si na elemencie 5 od ko ca, czyli 1: Zamieniamy te elementy ze sob : 5 2 8 1 4 0 4 6 8 2 1 5 7 6 9 5 2 1 1 4 0 4 6 8 2 8 5 7 6 9 Post puj c jak wy ej po lewej dochodzimy do elementu nr 8, czyli 6, a po prawej do 6 od ko ca, czyli 2: Jak zwykle zamieniamy je ze sob : 5 2 1 1 4 0 4 6 8 2 8 5 7 6 9 5 2 1 1 4 0 4 2 8 6 8 5 7 6 9 Id c od lewej zatrzymujemy si na 8, a od prawej na dwójce, poniewa nasze przegl dania od lewej i od prawej "spotkały si " tak wi c cofamy si w ka dym o jedn pozycj do tyłu i w ten sposób mamy wyznaczony podział: 5 2 1 1 4 0 4 2 8 6 8 5 7 6 9 Z tymi podtablicami post pujemy tak, jak z tablic wej ciow. Nie b d tutaj prezentował poszczególnych kroków sortowania. Elementem dziel cym po lewej jest Podstawy Informatyki 2 rok akad. 2003/2004 mgr in. Paweł Myszkowski 7
liczba 5, a po prawej liczba 8 (pierwsze w tych tablicach). Po podziale takim jak przeprowadzonym wy ej otrzymujemy: 2 2 1 1 4 0 4 5 6 6 7 5 8 8 9 Zauwa my, e dla liczby 5, która jest "sama" nie b dzie ju wywołania rekurencyjnego. Po nast pnym podziale otrzymamy: 0 1 1 2 4 2 4 5 5 6 7 6 8 8 9 W tym przypadku mógł by problem z podziałem tablicy 6,6,7,5. W tym przypadku z lewej strony i prawej doszli my do elementu drugiego, tj. liczby 6 i zatrzymali my si. Nie mo na zamieni elementu z nim samym. W tej sytuacji mo na przyj, e "sporna" liczba b dzie nale e do lewej lub do prawej strony. Przyj łem, e do prawej. Po nast pnym podziale otrzymamy: 0 1 1 2 4 2 4 5 5 6 7 6 8 8 9 Kolejny podział daje nam: 0 1 1 2 2 4 4 5 5 6 6 7 8 8 9 Po ostatnim podziale nasze dane b d wygl da nast puj co: 0 1 1 2 2 4 4 5 5 6 6 7 8 8 9 Teraz ł czymy wszystkie liczby i powstaje nast puj cy ci g: 0 1 1 2 2 4 4 5 5 6 6 7 8 8 9 Liczby s ju posortowane. Oczywi cie wszystkie podziały s wykonywane rekurencyjnie. Poprzez zastosowanie rekurencyjno ci algorytm QuickSort ma zwi zły kod i jest łatwy w implementacji. Inna odmiana QuickSort Problem długo ci wykonania wyst puje w przypadku, gdy tablica wej ciowa jest posortowana odwrotnie, tzn. jej wyrazy stanowi ci g nierosn cy. Na przykład tak tablic mo e by : 9 8 7 6 5 4 3 2 1 0 Prosz spróbowa przeprowadzi algorytm QuickSort dla tych danych. Wynika to z tego, e jako element dziel cy dan tablic wybieramy jej pierwszy element. Dla tablicy powy ej takie zało enie powoduje, e za ka dym razem granica podziału jest za pierwsz liczb tej tablicy. Mo na oczywi cie wybra inny element jako granic podziału. W ten spowodujemy, e algorytm szybkiego sortowania dla wy ej przedstawionych danych b dzie działał du o szybciej. Ale który element wybra? Najlepiej wylosowa. Jak si okazuje to bardzo dobre rozwi zanie, które nie wymaga du o oblicze. Najbardziej optymalnym rozwi zaniem jest wybranie mediany (najbardziej " rodkowego" elementu tablicy). Jednak e wymaga to du o dodatkowego czasu. Mo na tak e zmiesza losowanie liczb z wyborem mediany. Po prostu losujemy z tablicy do podziału pewn ilo liczb (najlepiej 3) i wyznaczamy w ród nich median, czyli element rodkowy pod wzgl dem warto ci. Nast pnie dokonujemy podziału według tego elementu. Podstawy Informatyki 2 rok akad. 2003/2004 mgr in. Paweł Myszkowski 8
W j zyku C zaimplementowana została funkcja realizuj ca szybkie sortowanie. Jest to funkcja qsort(), znajduj ca si w module <stdlib.h> i <search.h>.. Oto jej nagłówek: void qsort(void *base, size_t nelem, size_t width, int (*fcmp)(const void *, const void *)); Jej parametry to (kolejno): a) zrzutowany adres pierwszego elementu tablicy, b) liczba elementów tablicy, c) rozmiar pojedynczego elementu tablicy, d) funkcja porównuj ca, która zwraca: 0 gdy elementy porównywane s równe, liczb dodatni gdy pierwszy element jest wi kszy ni drugi, liczb ujemn gdy drugi element jest wi kszy ni pierwszy. Oto przykład ilustruj cy działanie i wywołanie funkcji qsort(): #include <stdio.h> #include <stdlib.h> #include <string.h> int sort_function( const void *a, const void *b); char list[5][4] = { "cat", "car", "cab", "cap", "can" }; int main(void) { int x; } qsort((void *)list, 5, sizeof(list[0]), sort_function); for (x = 0; x < 5; x++) printf("%s\n", list[x]); return 0; int sort_function( const void *a, const void *b) { return( strcmp((char *)a,(char *)b) ); } Podstawy Informatyki 2 rok akad. 2003/2004 mgr in. Paweł Myszkowski 9