ASD Algorytmy sortujące Marcin Mikołajczyk s3749 [email protected] Algorytmy sortujące Insertion Sort (sort. przez wstawianie) Quick Sort (sort.

Download Report

Transcript ASD Algorytmy sortujące Marcin Mikołajczyk s3749 [email protected] Algorytmy sortujące Insertion Sort (sort. przez wstawianie) Quick Sort (sort.

ASD
Algorytmy
sortujące
Marcin Mikołajczyk s3749
[email protected]
Algorytmy sortujące
1
Insertion Sort (sort. przez wstawianie)
2
Quick Sort (sort. szybkie)
3
Merge Sort (sort. przez scalanie)
4
Quick Sort vs. Merge Sort (porównanie)
Insertion Sort (sort. przez wstawianie)
Algorytm polegający na usuwaniu
pewnego elementu z danych
wejściowych i wstawianiu go na
odpowiednie miejsce w wynikach. Wybór
następnego elementu z danych jest
dowolny. Szybkość tego algorytmu zależy
od struktury danych wyjściowych i
implementacji operacji wstawiania.
 Złożoność obliczeniowa: O(n²)
Insertion Sort (sort. przez wstawianie)
Zalety algorytmu:
 szybkość sortowania już posortowanych lub
prawie posortowanych elementów
 efektywny dla zbiorów o niewielkiej
liczebności
 stabilny
 prosty do interpretacji
Wada algorytmu:
 wymaga dodatkowej pamięci komputera
Insertion Sort (sort. przez wstawianie)
 Zasada działania





Utwórz zbiór elementów posortowanych i przenieś do
niego dowolny element ze zbioru nieposortowanego.
Weź dowolny element ze zbioru nieposortowanego.
Wyciągnięty element porównuj z kolejnymi elementami
zbioru posortowanego póki nie napotkasz elementu
równego lub elementu większego (jeśli chcemy otrzymać
ciąg niemalejący) lub nie znajdziemy się na
początku/końcu zbioru uporządkowanego.
Wyciągnięty element wstaw w miejsce gdzie skończyłeś
porównywać.
Jeśli zbiór elementów nieuporządkowanych jest niepusty
wróć do punkt 2.
Insertion Sort (sort. przez wstawianie)
Przykład

Problem można dobrze zilustrować na przykładzie układania kart.

Wyobraź sobie, że trzymasz w ręku 5 kart o "wartościach": 5, 2, 4, 7, 3.
Przekładamy teraz do drugiej ręki pierwszą kartę - czyli 5.
W I ręce mamy: 2, 4, 7, 3. W drugiej: 5.

Znowu przekładamy pierwszą kartę. Trzeba ją włożyć do drugiej ręki w odpowiednie
miejsce!
W I ręce mamy: 4, 7, 3. W drugiej: 2, 5.

Potem bierzemy kartę 4. ...i wkładamy ją do drugiej ręki w odpowiednie miejsce (trzeba
je WYSZUKAĆ).
W I ręce mamy: 7, 3. W drugiej: 2, 4, 5.

Teraz 7.
W I ręce mamy: 3. W drugiej: 2, 4, 5, 7.

I na koniec bierzemy: 3.
W I ręce mamy: [pusto]. W drugiej: 2, 3, 4, 5, 7.
Jak widać jest to bardzo prosty rodzaj sortowania. W takiej postaci można go w prosty
sposób stosować do sortowania list. W przypadku tablic insertion-sort wymaga niestety
przesuwania wielu elementów tablicy, dlatego jest dosyć czasochłonny.
Insertion Sort (sort. przez wstawianie)

Pseudokod
for k = 2 to n do // k to początek zbioru
nieposortowanego
element = A[k]
i = k-1
while( i>0 )and( A[i]>element ) do //szukamy
miejsca i tworzymy rozstęp
A[i+1] = A[i] //przesuwamy elementy
i = i-1
a[i+1] = element //wstawiamy element tuz za
mniejszym
Uwaga:
W pętli while przesuwamy elementy, dopóki są większe niż pamiętany
element. Kiedy pętla się zakończy, wstawiamy pamiętany element w A[i+1] będzie to miejsce po mniejszym i przed większym elementem, ewentualnie
początek lub koniec (zbioru posortowanego [1..k])
Quick Sort (sort. szybkie)
Quick Sort jest najlepszą z poznanych
dotychczas metod sortowania. Jest ona
metodą typu “divide and conquer” (“dziel
i rządź”).
 Złożoność obliczeniowa: O(nlogn), jednak
przy złym wyborze piwota i niekorzystnych
danych wejściowych może wynieść Θ(n²)
Quick Sort (sort. szybkie)
 Zalety algorytmu:
 działa prawie w miejscu (używając niewielkiego stosu
pomocniczego)
 ma wyjątkowo skromna pętlę wewnętrzną
 Wady algorytmu:
 jest niestabilny
 jest wrażliwy (czasami prosty niezauważony błąd w
implementacji może powodować niewłaściwe
działanie w przypadku niektórych danych)
Quick Sort (sort. szybkie)

Zasada działania
Metoda tego algorytmu polega na dzieleniu sortowanego ciągu na odpowiednio wybrane
podciągi i dla każdego z otrzymanych podciągów (z ilością elementów >= 2) wywołaniu
(rekurencyjnym) ponownie samej siebie.
Bardziej szczegółowo:
Dla danego ciągu najpierw wyznaczany jest tzw. znacznik podziału. Może on być wybierany na
różne sposoby. Najczęstszymi sposobami wyboru znacznika podziału są:

element wzięty ze środka ciągu;

element wylosowany spośród elementów ciągu;

mediana kilku elementów wybranych lub wylosowanych z ciągu.
Następnie QS porządkuje ciąg w ten sposób, by w pierwszej jego części znalazły się tylko
elementy <= x (pierwszy podciąg), potem ewentualnie jeden element = x (drugi podciąg), a
potem elementy >= x (trzeci podciąg). Każdy z tych podciągów może być pusty (ale oczywiście
nie wszystkie naraz). Następnie jeśli pierwszy podciąg zawiera co najmniej 2 elementy, to ten
podciąg też trzeba uporządkować (jego dane, czyli początek i koniec, trafiają na stos).
Podobnie dzieje się dla podciągu trzeciego. Całość jest powtarzana aż do momentu, gdy
wszystkie podciągi będą uporządkowane (stos będzie pusty), czyli aż cały wyjściowy ciąg
będzie posortowany.
Quick Sort (sort. szybkie)

Pseudokod
połóż na stos (1, n)
dopóki stos niepusty rób
zdejmij ze stosu (L, P)
i := L; k := P;
x := tab[(L + P) div 2] //x to znacznik podziału
dopóki i <= k rób
dopóki tab[i] < x rób
i := i + 1
dopóki tab[k] > x rób
k := k - 1
jeśli i <= k
zamień tab[i] z tab[k]
i := i + 1; k := k - 1
jeśli L < k
połóż na stos (L, k)
jeśli i < P
połóż na stos (i, P)
Merge Sort (sort. przez scalanie)
Jest to algorytm typu dziel i rządź.
Ideą działania tego typu algorytmów
jest podział problemu na mniejsze
części, których rozwiązanie jest już
łatwiejsze.
 Złożoność obliczeniowa: O(nlogn), jednak wymaga
O(n) dodatkowej pamięci
Merge Sort (sort. przez scalanie)
Zalety algorytmu:
 złożoność jest zawsze taka sama,
niezależnie od danych wejściowych (czasami
może to jednak być wadą)
 jest stabilny
Wady algorytmu:
 najdłużej trwa sortowanie zbioru
nieuporządkowanego
Merge Sort (sort. przez scalanie)
 Scalanie lub zestawianie oznacza łączenie dwóch
lub więcej uporządkowanych zbiorów w jeden
uporządkowany. Najprościej wykonać tę operację
porównując najmniejsze elementy obu zbiorów, a
następnie usuwając mniejszy, zapisawszy go
uprzednio do zbioru wyjściowego. Okazuje się, że
podany algorytm jest najskuteczniejszą metodą
scalania, o ile scalane ciągi są podobnej długości.
Jeżeli jeden z wejściowych ciągów jest znacznie
dłuższy od drugiego, można podać lepsze
algorytmy.
Merge Sort (sort. przez scalanie)
 Zasada działania
Podobnie jak omawiany wcześniej Quick Sort, sortowanie
przez scalanie jest przedstawicielem rodziny dziel i zwyciężaj.
Sortowanie odbywa się przez podzielenie wejściowego ciągu
na dwie równe części, posortowaniu każdej z nich i scaleniu
za pomocą opisanej wcześniej metody. Zauważmy, że proces
dzielenia kolejnych podtablic można kontynuować do
momentu, gdy staną się jednoelementowe. Ponieważ ciągi
jednoelementowe są uporządkowane, więc można dla nich
wykonać procedurę scalania opisaną powyżej. Ilustrację
sortowania przez scalanie stanowi rysunek.
Merge Sort (sort. przez scalanie)
 Etapy sortowania
Merge Sort (sort. przez scalanie)
 Pseudokod (A,p,r)
jeśli p < r to {
q := [p+r/2];
Merge − sort(A, p, q);
Merge − sort(A, q + 1, r);
Merge(A, p, q, r)
}
Algorytm przez scalanie powstaje przez wykorzystanie metody
”dziel i zwyciężaj” do projektowania algorytmu. Stąd składa się
z trzech procedur:

Dziel: ciąg n-elementowy na dwa [n/2] elementowe;

Zwyciężaj: sortuj każdy z otrzymanych podciągów (Merge-sort);

Połącz: oba posortowane ciągi w jeden (Merge).
Quick Sort vs. Merge Sort (porównanie)
Szczegółowym testom poddanych zostało pięć algorytmów
sortujących: BubbleSort sortowanie przez prosty wybór,
HeapSort, QuickSort oraz MergeSort. W dalszej części
prezentacji porównam dwa ostatnie.
Do sprawdzenia wydajności algorytmów w praktyce użyto
specjalnie przygotowaniej aplikacji, napisanej w środowisku
Borland C++ Builder 6.0 Personal Edition.
Test polegał na wykonaniu dwudziestu sortowań dla każdej
długości tablicy. Pod uwagę brane były trzy elementy: czas
działania, ilość wykonanych zamian oraz ilość porównań
porządkowanych elementów.
Quick Sort vs. Merge Sort (porównanie)
 Czas sortowania tablicy uporządkowanej
10
102
103
104
105
106
Quick Sort
5,866E-6
2,542E-5
0,0002
0,0033
0,0742
0,7405
Merge Sort
1,732E-5
8,101E-5
0,0008
0,1027
0,1625
1,9224
algorytm
il. elementów
 Czas sortowania tablicy odwrotnie uporządkowanej
10
102
103
104
105
106
Quick Sort
6,42E-6
2,82E-5
0,0002
0,0044
0,0575
0,7866
Merge Sort
1,704E-5
8,8E-5
0,0009
0,0122
0,1718
2,382
algorytm
il. elementów
Quick Sort vs. Merge Sort (porównanie)
 Średni czas sortowania
10
102
103
104
Quick Sort
7,123E-6
5,49E-5
0,0007
0,0095
Merge Sort
1,771E-5
9,886E-5
0,0012
0,015
algorytm
il. elementów
 Średnia liczba wykonanych zmian
10
102
103
104
Quick Sort
11,4
183,2
2507,8
32164,05
Merge Sort
19,3
196,8
1974,4
19749,4
algorytm
il. elementów
Quick Sort vs. Merge Sort (porównanie)
 Średnia liczba wykonanych porównań
10
102
103
104
Quick Sort
17,8
472,25
8038,85
106970,0
Merge Sort
8,05
93,4
948,2
9498,3
algorytm
il. elementów
Literatura
 Niniejsza prezentacja powstała m.in. w oparciu o
poniższe materiały:





http://edukacja.pwsz.pila.pl/~ochodek/sortowania/
http://www.i-lo.tarnow.pl/edu/inf/alg/algsort/index.html
http://si.ae.krakow.pl/~kurdziew/cpp/domowe/dodatkowe/algsort/
http://pl.wikipedia.org/wiki/Sortowanie
L. Banachowski, K.Diks, W.Rytter Algorytmy i struktury danych,
Wydawnictwa Naukowo-Techniczne, Warszawa 1996, 2001
http://pjwstk.nevada.pl