Problem sortowania można zdefiniować następująco:

Transkrypt

Problem sortowania można zdefiniować następująco:
Problem sortowania można zdefiniować następująco:


Danymi wejściowymi jest ciąg n liczb.
Wynikiem jest taka ich permutacja (czyli zmiana kolejności), że tworzą one ciąg
rosnący (niemalejący).
Zadaniem algorytmu sortowania jest takie przestawienie elementów danego ciągu, aby były
one uporządkowane rosnąco (niemalejąco).
Opis
Sortowanie jest jednym z najczęściej rozwiązywanych problemów informatycznych. Według
różnych autorów, komputery spędzają od 25 do 80 procent czasu na porządkowaniu
informacji. Porządek wśród elementów ułatwia i przyspiesza wykonywanie innych operacji
(np. przeszukiwania).
Sortowanie jest też przykładem problemu, który może być rozwiązany na wiele sposobów,
a ich efektywność jest istotnie różna. Za efektywność algorytmów sortujących przyjmuje się
liczbę porównań wykonywanych między elementami danych. Zwykle jest ona podawana jako
zależność od liczby elementów do uporządkowania.
Badanie efektywności metod sortowania.
Przy jednym komputerze dwóch koordynatorów: Przygotowują tabelkę taką jak inni, ale
do każdego rodzaju sortowania wpisują nazwiska osób od których dostaną wyniki.
Pozostali są w trzech grupach A, B i C. Ci z grup testują sortowania:
A: bąbelkowe, przez wstawianie, przez wstawianie binarne.
B: Przez wybór, przez scalanie, przez scalanie rozszerzone.
C: szybkie, stogowe, stogowe rozszerzone.
Wielkość danych 300. Wprowadzić tez np. wielkość danych = 10 i obserwować krok po
kroku.
Stabilny algorytm porządkowania to taki, w którym kolejność elementów względem siebie
w uporządkowanym ciągu jest taka sama, jak w ciągu danym do uporządkowania.
Porządkowanie w miejscu (in situ) Algorytm porządkowania przez scalanie nie może być
zapisany w tym samym miejscu w pamięci komputera, w którym były dane ciągi do scalenia,
nie jest to algorytm działający „w miejscu” – in situ. Ta własność ma duże znaczenie, bo
algorytmem działającym w miejscu można porządkować dwa razy dłuższe ciągi niż
algorytmem przez scalanie
Który z algorytmów porządkowania wykonuje najmniej działań na ciągu już
uporządkowanym, czy któryś algorytm nie wykonuje na takim ciągu żadnych działań?
Uporządkuj je w kolejności.
Przecież ciąg jest uporządkowany. (niestety jest to cena jaką płacimy za uniwersalność algorytmów
porządkowania, niezerowa liczba działań wykonywana nawet na ciągu uporządkowanym)
Który algorytm wykonuje najmniej operacji na ciągach uporządkowanych w odwrotnej
kolejności.
Rodzaj
sortowania
Ciąg z danymi
przypadkowymi
1. Bąbelkowe
43 893
(BubbleSort)
435
WD=30
2. Przez
21 975
wstawianie
226
(InsertonSort)
WD=30
3. Wstawianie
2 473
binarne
144
4. Przez wybór – 45 150
wybieranie
465
(SelectionSort)
WD=30
5. Przez scalanie 2 094
(MergeSort)
112
WD=30
Dane
posortowane
Dane odwrotnie
posortowane
299
29
44 850
435
44 850
435
398
29
3 012
192
45 150
465
1 822
78
45 150
465
1 239
71
1 308
77
6. Scalanie
rozszerzone
7. Szybkie
(QuckSortHoare)
WD=30
2 106
111
2 353
110
1 239
71
44 850
435
1 308
77
35 820
435
8. Stogowe
(HeapSort –
Floyd)
WD=30
Stogowe
rozszerzone
Wielkość danych
=30
4 052
204
4 227
211
3 771
188
203
211
188
Złożoność
czasowa/
pamięciowa
O(n2)
O(n2) / O(1)
stabilny
nlog2n
O(n2) / O(1)
niestabilny
O(nlog2n-n)/
O(n)
stabilny, nie
działa w miejscu
pesymistyczny
O(n2)/ O(n)
oczekiwana
O(nlogn)/
O(logn)
niestabilny
O(nlogn)/ O(1)
niestabilny
Dane przypadkowe: 5 (scalanie - 2094) i 6 (scalanie rozszerzone - 2106), 7 (szybkie - 2353),
3 (wstawianie binarne - 2473), 8 (stogowe - 4052), 2 (wstawianie – 21 975), 1 (bąbelkowe –
43893), 4 (wybór – 45150).
Dane uporządkowane: 1 (Bąbelkowe – 299), 5 i 6 (scalanie i scalanie rozszerzone– 1239), 3
(wstawianie binarne – 3012), 8 (stogowe – 4227), 7 (szybkie – 44850), 2 (Wstawianie –
44850), 4 (wybór- 45 150).
Dane odwrotnie uporządkowane: 2 (Wstawianie – 398), 5 i 6 (scalanie i scalanie
rozszerzone– 1239), 3 (wstawianie binarne – 1822), 8 (stogowe – 3771), 7 (szybkie – 35820),
1 (Bąbelkowe – 44850), 4 (wybór- 45 1500).
Rodzaj
sortowania
Ciąg z danymi
przypadkowymi
1. Bąbelkowe
Przestawianie kolejnych elementów i sprawdzanie czy nastąpiło
Dane
posortowane
Dane odwrotnie
posortowane
Złożoność
czasowa/
pamięciowa
O(n2)
(BubbleSort)
WD=30
2. Przez
wstawianie
(InsertonSort)
3. Wstawianie
binarne
4. Przez wybór –
wybieranie
(SelectionSort)
przestawienie. Przyjęto, że nie sortuje się tą metodą więcej niż
5000 elementów. Dane posortowane O(n)
Układanie kart w ręku. Wyjmujemy kolejny element i wstawiamy
w posortowany ciąg. Polecany do krótkich ciągów.
Dane posortowane O(n)
A(n)= ¼ n2 + O(n) – oczekiwana zł. czasowa trochę lepsza niż
SelectionSort, ale tego samego rzędu
W(n)= ½ n2+O(n)
Stosuje przeszukiwanie binarne dla znalezienia miejsca dla j-go
elementu. Pomysłodawcą był Hugo Steinhaus w 1950 r.
Bierze się 1 element i zamienia z najmniejszym z całego zbioru,
potem 2 itd. Ustawianie książek na półce.
Optymalny jeśli chodzi o liczbę przestawień – tylko n-1.
U Diksa - Stabilność osiąga się kosztem zwiększenia
współczynnika proporcjonalności złożoności
W(n)= A(n)= ½ n2-O(n)
Stabilny
In situ
O(n2) / O(1)
Stabilny (zależy od
implementacji)
In situ
O(nlogn)
porównań
O(n2) / O(1) In
situ
Stabilny (zależy od
implementacji, często
piszą, że
niestabilny – Diks
też)
5. Przez scalanie
(MergeSort)
łączenie
6. Scalanie
rozszerzone
7. Szybkie
(QuckSortHoare, 1962 r)
8. Stogowe
(HeapSort –
Floyd)
Też rekurencyjny. Prosty podział ciągu na pół. Rekurencyjnie aż
do 1 elementu, potem następuje łączenie, wstawianie w
określonym porządku.
Zaproponował tę metodę John von Neumann w 1945 r.
O(nlogn)/ O(n)
stabilny, nie
działa w miejscu
Rekurencyjny algorytm sortowania, zasada "dziel i zwyciężaj". Na
każdym etapie rekurencji (przetwarzane coraz mniejsze fragmenty
oryginalnej listy) przetwarzanie obejmuje 3 etapy:
Umieszczanie (arbitralnie, np. ostatniego lub pierwszego, najlepiej
wybrany losowo) wybranego elementu na jego pozycji docelowej.
Umieszczanie na lewo od niego wszystkich elementów od niego
mniejszych. Przesuwa się indeks w prawo
Umieszczanie na prawo od niego wszystkich elementów od niego
większych. Przesuwa się indeks w lewo.
Dzielenie kończy się, gdy 2 wskaźniki się spotkają.
Może być nierekurencyjne, wówczas poprawia się złożoność
pamięciową z O(n) na O(logn). Jedno wywołanie rekurencyjne
zastąpić iteracją
W(n)=O(n2)
A(n)=O(nlogn)
Przez kopiec rozumiemy drzewo binarne, które spełnia warunek
kopca, czyli jeśli węzeł x jest następnikiem węzła y, to element
w węźle x jest nie większy niż element w węźle y. Kopiec zupełny
ma wypełnione wszystkie poziomy całkowicie, z wyj. Ostatniego
wypełnionego od strony lewej
Pesymistyczny przypadek nie jest dużo gorszy od średniego.
W(n)= 2nlogn+O(n)
2 fazy: faza budowy kopca i właściwe sortowanie.
pesymistyczny
O(n2)-przy już
posortowanym/
oczekiwana
O(nlogn)/
O(logn)
niestabilny
in situ
pam. O(n), bo
wymaga stosu
O(nlogn)/ O(1)
Niestabilny
In situ
Stogowe
rozszerzone
n2 jest górnym ograniczeniem na złożoność czasową problemu sortowania
Stabilność tzn. zachowanie początkowego ustawienia elementów względem siebie
Operacją dominującą przyjmuje się porównania elementów w ciągu.
Złożoność pamięciowa to ilość dodatkowej pamięci (oprócz n miejsc dla elementów ciągu),
potrzebnej do wykonania algorytmu.
W(n) – pesymistyczna złożoność czasowa
A(n) – oczekiwana złożoność czasowa