Algorytmy sortowania Przez „sortowanie” rozumiemy porzdkowanie elementów tablicy; takie jej przekształcenie, aby jej elementy układały si – w zalenoci od potrzeb – rosnco lub malejco. a) sortowanie bbelkowe W tej metodzie w kadym obiegu ptli wewntrznej przebiegamy przez wszystkie elementy tablicy porównujc kady z nich z elementem po nim nastpujcym. Jeeli dane dwa elementy nie zachowuj okrelonego porzdku (np. gdy chcemy posortowa tablic rosnco, a pierwszy jest wi kszy ni drugi) zamieniamy je miejscami. Ptla zewntrzna wykonuje si tak długo, dopóki w ptli wewntrznej wystpi przynajmniej jedna zamiana. Nazwa pochodzi od faktu, e skrajne elementy okrelonego porzdku (np. w sortowaniu rosncym element najwi kszy, w malejcym najmniejszy) wdruj kolejno na koniec tablicy, tak jak pcherzyki powietrza w wodzie unosz si do góry. Przykład Posortuj metod b belkow zbiór piciu elementów: 9 5 6 3 1 w porz dku rosncym. Funkcja porównuj ca przyjmuje posta : f p (a, b ) → a ≤ b Rozpisany pierwszy obieg sortowania: 9 5 6 3 1 Porównujemy pierwszy element z drugim. 9>5, zatem elementy zamieniamy miejscami. 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. 1 obieg W celu posortowania całego zbioru nale y 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 ko cu, 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 najwi kszy 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 bbelkowym kolejne obiegi umieszczaj na właciwych miejscach w porzdkowanym zbiorze kolejne elementy maksymalne. Algorytm sortowania b belkowego 1. Je li liczba elementów w zbiorze jest mniejsza od 2, koczymy algorytm. 2. Rozpoczynamy od pierwszego elementu. 3. Biecy 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 biecy element nie jest przedostatnim elementem zbioru, to przesuwamy si do kolejnego elementu i wracamy do punktu 3. 5. Je li w trakcie przegldania 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 przegldanych elementów fp() – funkcja porównuj ca x – zmienna pomocnicza, wykorzystywana przy wymianie zawarto ci elementów di – 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 wczeniej algorytmu sortowania bbelkowego jest du o szybszy i bardziej efektywny, lecz oczywi cie bardziej zło ony koncepcyjnie. Zasada działania tego algorytmu przypomina układanie w rce kart pobieranych kolejno z talii. Przykład 9 5 6 3 1 3 9 5 6 1 s 3 1 9 5 6 1 obieg 3 9 5 6 1 9 5 6 1 3 Podstawy Informatyki 2 Na kocu zbioru tworzymy tzw. list uporz dkowanych elementów. Pocz tkowo lista ta zawiera tylko jeden, ostatni element zbioru. Ze zbioru wyci gamy element le cy bezpo rednio przed list uporz dkowan . Tutaj jest to liczba 3. Zajmowane przez ni miejsce w zbiorze staje si wolne. Wyci gni ty element porównujemy kolejno z elementami listy, a napotkamy jej koniec lub element wikszy lub równy. Poniewa element listy jest mniejszy od bie cego elementu, przesuwamy go w zbiorze na zwolnione miejsce. Puste miejsce przemieszcza si wg ł b listy uporz dkowanej. Na li cie uporz dkowanej nie ma wicej elementów do porównania. Zatem element bie cy umieszczamy w zbiorze na wolnym miejscu. Zwró uwag, i przemie cił si on w stosunku do swojej pozycji pierwotnej, a na kocu zbioru powstała dwuelementowa lista uporz dkowana. 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. Je li zbiór zawiera mniej ni dwa elementy, to koczymy. 2. Na kocu zbioru tworzymy list uporz dkowanych elementów. Pocz tkowo lista ta obejmuje jeden, ostatni element. 3. Sortowanie rozpoczynamy od elementu le cego w zbiorze tu przed list uporz dkowan . Element wyci gamy ze zbioru. Miejsce zajmowane przez niego staje si wolne. 4. Wyci gni ty element porównujemy kolejno z elementami na li cie uporz dkowanej. Je li element listy jest mniejszy (ze wzgldu na porz dek wyznaczony przez funkcj porównuj c ) od elementu wyci gni tego, to przesuwamy go na wolne miejsce. Operacj t powtarzamy dot d, a napotkamy koniec listy lub element wikszy lub równy elementowi wyci gnitemu. 5. Element wyci gnity wstawiamy na wolne miejsce. Rozmiar listy uporz dkowanej ro nie o 1 element. 6. Je li lista uporz dkowana nie obejmuje jeszcze całego zbioru, to przechodzimy do punktu 2. 7. W przeciwnym wypadku koczymy algorytm. Oznaczenia: D – zbiór do posortowania n – liczba elementów w zbiorze D i, j – zmienne licznikowe p tli x – zmienna pomocnicza przechowuj ca wybrany element di – i-ty element zbioru D fp( ) – funkcja porównujca dwa elementy zbioru D Podstawy Informatyki 2 rok akad. 2003/2004 mgr in . Paweł Myszkowski 4 c) sortowanie przez wybór Algorytm 1. Je li zbiór liczy mniej ni dwa elementy, to koczymy. 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 porównuj ca przyjmie zatem posta : w porz dku rosn cym. Funkcja f p ( a, b) → a ≤ b 9 5 6 3 1 Znajdujemy najmniejszy element w zbiorze. Jest nim liczba 1. 1 5 6 3 9 Element ten wymieniamy z pierwszym elementem zbioru. Element ten jest ju na swojej wła ciwej 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 uporz dkowane. 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. Je li zbiór ma mniej ni dwa elementy, koczymy. 3. Za pomoc funkcji porównuj cej sprawdzamy kolejno element tymczasowy z pozostałymi elementami zbioru. Je li w wyniku porównania elementu tymczasowego z elementem zbioru funkcja porównuj ca da wynik false (dla elementu najwikszego da wynik true), to za nowy element najmniejszy (najwikszy) przyjmujemy dany element zbioru i kontynuujemy przegl danie. Przykład Znale najmniejszy element w zbiorze 4 7 3 2 5 1 w porz dku rosn cym. 4 Za tymczasowy element najmniejszy przyjmujemy pierwszy 4 7 3 2 5 1 element zbioru, czyli liczb 4. 4 f (4, 7) = true – przechodzimy do nast pnego elementu 4 7 3 2 5 1 p 4 f (4,3) = false – zast pujemy 4 liczb 3, itd. 4 7 3 2 5 1 p D – sortowany zbiór n – liczba elementów w zbiorze D i, j – zmienne licznikowe p tli m – przechowuje indeks elementu minimalnego fp( ) – funkcja porównuj ca dwa elementy ze zbioru D x – zmienna pomocnicza, uywana przy wymianie zawarto ci elementów di – 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 duych 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. Kady element pierwszej tablicy nie jest wi kszy ni kady 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 pujc tablic : 578140468215269 Liczb, według której b dziemy wykonywa podział b dzie pierwsza liczba danej tablicy - w tym przypadku jest to 5. Na pocztku 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. 578140468215269 Elementy, które ju "przeszli my" s pogrubione, ate, 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: 528140468215769 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: 528140468215769 Zamieniamy te elementy ze sob: 521140468285769 Post pujc jak wyej po lewej dochodzimy do elementu nr 8, czyli 6, a po prawej do 6 od ko ca, czyli 2: 521140468285769 Jak zwykle zamieniamy je ze sob: 521140428685769 Idc 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 kadym o jedn pozycj do tyłu i w ten sposób mamy wyznaczony podział: 52114042 8685769 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 wyej otrzymujemy: 2211404 5 6675 889 Zauwamy, e dla liczby 5, która jest "sama" nie b dzie ju wywołania rekurencyjnego. Po nast pnym podziale otrzymamy: 011 2424 5 5 676 8 89 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 mona zamieni elementu z nim samym. W tej sytuacji mona przyj, e "sporna" liczba b dzie nalee do lewej lub do prawej strony. Przyjłem, e do prawej. Po nast pnym podziale otrzymamy: 0 11 2 424 5 5 6 76 8 8 9 Kolejny podział daje nam: 0 1 1 2 2 44 5 5 6 6 7 8 8 9 Po ostatnim podziale nasze dane b d wygl da nast pujco: 0 1 1 2 2 4 4 5 5 6 6 7 8 8 9 Teraz łczymy wszystkie liczby i powstaje nast pujcy ci g: 011224455667889 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 cig nierosncy. Na przykład tak tablic moe by: 9876543210 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 powyej takie załoenie powoduje, e za kadym razem granica podziału jest za pierwsz liczb tej tablicy. Mona oczywi cie wybra inny element jako granic podziału. W ten spowodujemy, e algorytm szybkiego sortowania dla wyej przedstawionych danych b dzie działał duo szybciej. Ale który element wybra? Najlepiej wylosowa. Jak si okazuje to bardzo dobre rozwi zanie, które nie wymaga duo oblicze . Najbardziej optymalnym rozwi zaniem jest wybranie mediany (najbardziej " rodkowego" elementu tablicy). Jednake wymaga to duo dodatkowego czasu. Mona take 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 realizujca szybkie sortowanie. Jest to funkcja qsort(), znajdujca 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ównujca, 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 ilustrujcy 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