ASD W3

background image

1

Algorytmy i Struktury

Danych

Wykład 3

background image

2

Sortowanie – definicja i

cele

Sortowanie - uporządkowanie zbioru danych względem

pewnych cech charakterystycznych każdego elementu
tego zbioru (np. wartości każdego elementu, np.
sortowanie liczb rosnąco, słów alfabetycznie itp.)

Cele:
 uporządkowanie danych,
 umożliwienie stosowania wydajniejszych algorytmów

(np. wyszukiwania)

 prezentacja danych w sposób czytelniejszy dla

człowieka.

background image

3

Sortowanie danych

Jest wiele metod sortowania danych.
Dobór odpowiedniej metody zależy od wielu

czynników. Są to m.in.

 rodzaj danych,
 ilość danych,
 wspólne cechy charakterystyczne danych.

Wszystkie metody sortowania będą

przedstawione na przykładzie sortowania

tablicy liczb.

background image

4

Sortowanie przez

wstawianie (ang.

insertion sort)

1.

Zakładamy, że pierwszy element tablicy

jest posortowany.

2.

Bierzemy kolejny,przenosimy do zmiennej

pomocniczej (tmp) i porównujemy elementy

już posortowane z tmp. Jeśli te elementy są

większe od tego w tmp, to przesuwamy je o

jedną pozycję w prawo.

3.

Na końcu (po zakończeniu przesuwania)

wstawiamy element z tmp do pozostałej

komórki tablicy.

background image

5

Sortowanie przez

wstawianie przykład

background image

6

Zaleta

Sortuje on tylko tablice wtedy, gdy

jest to potrzebne. Jeśli nasza

tablica będzie już posortowana

(może to być część tablicy), to

działanie algorytmu polega jedynie

na pobraniu wartości do zmiennej

tmp i odstawieniu jej na miejsce. Nie

wykonujemy żadnych przesunięć.

background image

7

Wady

1. Może się zdarzyć, że liczby, które znajdowały

się już na odpowiednich pozycjach są i tak
przesuwane
. W powyższym przykładzie ma to
miejsce dla liczby 7, która w tablicy wejściowej
zajmowała 2 pozycję i pomimo przesunięć, w
ostateczności powróciła na 2 pozycję.

2. Podczas wstawiania liczby do tablicy należy

przesunąć wszystkie większe (mniejsze)
elementy w prawo.
W najgorszym przypadku
trzeba przesunąć wszystkie elementy w tablicy.

background image

8

Algorytm ten wykonuje się w n-1 krokach (gdzie

n to ilość elementów do posortowania), a w

każdym kroku wykonujemy jeszcze pewną

ilość przesunięć (porównań i wstawień) –

zależną od położenia sortowanej liczby.

Możliwe są dwa skrajne przypadki:

1.

tablica całkowicie posortowana

2.

tablica posortowana w odwrotnej kolejności

Oraz przypadek pośredni, gdy elementy

tablicy są rozmieszczone przypadkowo.

background image

9

tablica całkowicie

posortowana

W tym przypadku ilość kroków będzie

równa n-1, a ilość „przesunięć” w
każdym kroku 1 (liczba będzie
porównana i wstawiona w to samo
miejsce).

Zatem złożoność w tym przypadku

wyniesie O(n).

background image

10

tablica posortowana w

odwrotnej kolejności

 ilość kroków wyniesie także n-1,

natomiast w każdym k-tym kroku
będzie wykonane k przesunięć
(maksymalna liczba). Zatem ilość
przesunięć w n-1 krokach wyniesie:

czyli złożoność pesymistyczna
tego algorytmu to O(n

2

)

(kwadratowa).

background image

11

Wpływ struktury danych na

efektywność wykonania

algorytmu

Implementacja oraz efektywność

poszczególnych kroków (podczas
takiego i innych sortowań) zależy od
struktury danych, której używamy.
Np.wstawianie lub usuwanie jest
prostsze jeżeli używamy listy
(szczególnie dwukierunkowej), a nie
statycznej tablicy.

background image

12

Sortowanie przez wybór -

przykład

background image

13

Sortowanie przez wybór

(ang. selection sort)

1. Zaczynamy od pustej części posortowanej, czyli cała

tablica tworzy część nieposortowaną.

2. Przeszukujemy nieposortowaną podtablicę w celu

znalezienia minimum,

3. Jeśli te minimum jest mniejsze od pierwszego

elementu tablicy nieposortowanej to zamieniamy je

miejscami (możliwe, że są one identyczne lub

minimum jest na tej właśnie pozycji, wtedy nic nie

robimy).

4. Przemianowujemy jeden element z części

nieposortowanej do posortowanej.

5. Wracamy do punktu 2.

background image

14

background image

15

Złożoność

(operacja istotna:

porównania)

 Czynność tą wykonujemy n-1 razy, gdzie

n to ilość liczb w tablicy (ostatni element

sam trafia na swoje miejsce)

 Musimy więc wykonać n-1 kroków (n to

ilość elementów w tablicy), a w każdym

kroku wykonujemy przeszukanie

podtablicy o (n-1)-k elementach (k to

numer kroku). Zatem suma porównań

jakie trzeba wykonać będzie wynosić:

background image

16

Złożoność (operacja

istotna: zamiana

elementów miejscami)

Pesymistycznie: musimy w każdym

kroku dokonać zamiany miejscami,
czyli n-1 kroków (n to ilość elementów
w tablicy)

Czyli f(n) = n-1, czyli złożoność O(n)

Optymistycznie: nie musimy wykonać

ani jednej zamiany, bo wszystkie
elementy są „na swoich miejscach”

background image

17

Sortowanie bąbelkowe

 Bierzemy ostatni element tablicy i

porównujemy z poprzednim. Jeśli jest
mniejszy to zamieniamy pozycjami i
porównujemy ten mniejszy znów z
sąsiednim

background image

18

Sortowanie bąbelkowe

(ang.bubble exchange

sort)

 Można to porównać do bąbelków, które

są lżejsze i idą w gorę. Ostatni element

tablicy wrzucamy do bąbelka.

 Jeśli poprzedni jest mniejszy (lżejszy) to

bąbelek zostawia większy element i

zabiera ten mniejszy (lżejszy). Porównuje

go z kolejnym sąsiadem i znów to samo...

Robimy tak długo,aż bąbelek nie dotrze

do części posortowanej tablicy.

background image

19

Sortowanie bąbelkowe -

złożoność

Wykonamy dokładnie n-1 kroków, a w

każdym kroku wykonamy (n-1)-k
porównań, czyli:

background image

20

Sortowanie bąbelkowe

ulepszone

 Algorytm ten można nieco ulepszyć. Może się zdarzyć

tak, że elementy tablicy są częściowo posortowane,

jak np. 1 3 5 8 4 2

 Jeśli bąbelek przejdzie z dołu do góry i żadne komórki

nie zostaną zamienione miejscami to oznacza to, że

tablica jest już posortowana i można zakończyć.

 Przy implementacji realizuje się to przy pomocy

dodatkowej zmiennej logicznej, która na początku

każdego cyklu bąbelka będzie ustawiana na false, a

jakakolwiek zamiana miejscami elementów powoduje

jej ustawienie na true. W ten sposób będziemy mogli

kontrolować, czy były dokonywane jakieś zamiany.

background image

21

Sortowanie bąbelkowe

ulepszone - złożoność

W przypadku optymistycznym, gdy

tablica będzie posortowana zostanie
wykonane n-1 porównań (jeden bąbelek) i
żaden element nie zostanie zamieniony.

W przypadku pesymistycznym, gdy

elementy są posortowane odwrotnie niż
powinny wykonamy n-1 kroków, a w
każdym kroku wykonamy (n-1)-k
porównań, czyli:

background image

22

Sortowanie przez

zliczanie (ang.

counting sort)

 Jeżeli wiemy, że liczby do

posortowania są ze skończonego
zbioru liczb całkowitych, to możemy
skorzystać z tej wiedzy i zmniejszyć
złożoność algorytmu sortowania.

background image

23

Przykład: tablica zawiera

liczby z przedziału <0;

3>

 Aby posortować te liczby tworzymy dodatkową

tablicę o dokładnie takiej liczbie komórek jak ilość
liczb mieszcząca się w przedziale k 0,3>. Dla

naszego przykładu będzie to tablica 4 elementowa
(w C/C++).

 Teraz należy przejść tablicę wejściową

(nieposortowaną) i zliczyć ilość wystąpień
poszczególnych liczb w tej tablicy, a wynik zliczania
wstawiać do tablicy pomocniczej pod odpowiednim
indeksem.

background image

24

 Następnie wypisujemy z tablicy zliczeń

odpowiednią ilość każdego elementu
w kolejności rosnącej i gotowe!

background image

25

Sortowanie przez

zliczanie - złożoność

 Złożoność takiego algorytmu sortowania

jest równa O(n) ze względu na operacje

zliczania (zwiększania o jeden elementu w

tablicy zliczającej) oraz tworzenia tablicy

posortowanej.

 Pozwala to sortować niezwykle szybko (w

porównaniu do innych algorytmów

sortowania), przy założeniu, że wiemy

jakie elementy się mogą pojawić.

Potrzebna jest też określona ilość

dodatkowej pamięci na tablicę zliczającą.

background image

26

Sortowanie stabilne

 Sortowanie stabilne to taki rodzaj

sortowania, który zachowuje
kolejność elementów o tej samej
wartości w ciągu wejściowym i
wyjściowym. Innymi słowy ma
znaczenie, który z elementów o tej
samej wartości będzie pierwszy.

background image

27

 Dla omówionego wcześniej sortowania przez

zliczanie zastosujemy sortowanie stabilne.
Do cyfr o tej samej wartości dopisano
indeksy, które mówią o kolejności
wystąpienia tych samych cyfr w tablicy
wejściowej.

background image

28

Sortowanie pozycyjne

(ang. radix sort)

 Problem sortowania ciągów znaków lub liczb

wielocyfrowych można rozwiązać

wykorzystując sortowanie pozycyjne.

 Sortowanie to odbywa się w grupach od lewej

do prawej lub odwrotnie.

 Jeśli chcemy posortować ciąg znaków (np.

nazwiska) sortować będziemy od lewej do

prawej.

 Aby posortować liczby poruszmy się w

odwrotnym kierunku.

background image

29

 Rozważamy dla przykładu liczby trzy

cyfrowych, które należy posortować
rosnąco.

 Wykorzystując stabilne sortowanie przez

zliczanie sortujemy względem liczb na
poszczególnych pozycjach. Wbrew
pozorom sortowanie rozpoczynamy od
pozycji najmniej znaczących (jedności)
i poruszamy się w „lewo”.

background image

30

 W pierwszym kroku sortujemy liczby

sugerując się jedynie ostatnia cyfrą, w
drugim kroku przedostatnią, a w ostatnim
kroku bierzemy pod uwagę jedynie
pierwszą cyfrę.

 W ten sposób nasza tablica liczb zostanie

posortowana. Warto rownież zauważyć, że
jeśli któraś z liczb ma mniejszą ilość cyfr to
należy z przodu uzupełnić ją zerami.

background image

31

background image

32

 Złożoność takiego algorytmu

wynosi kn, gdzie k to ilość cyfr w
liczbie (stosujemy sortowanie przez
zliczanie, bo wiemy, że cyfry są
tylko i wyłącznie dziesiętne), co
daje w notacji złożoność O(n).

background image

33

Sortowanie kubełkowe

(ang. bucket sort)

 Jest to metoda pozwalająca

posortować liczby całkowite. Do
tego celu wykorzystamy 10
kubełków ponumerowanych od 0 do
9. Do każdego będziemy wkładać
odpowiednio liczby.

background image

34

 Na początku umieszczamy liczby w kubełkach

sugerując się cyfrą jedności. Przykładowo, jeśli

cyfra ta jest równa 0 to liczba taka trafi do

kubełka zerowego, gdy 1 to do kubełka

pierwszego, itd. Ważna jest jednak kolejność

liczb w kubełku. Muszą on bowiem być tam

umieszczane w kolejności wystąpienia w ciągu.

Dlatego podczas implementacji kubełka należy

skorzystać z kolejki (struktura dynamiczna!). W

ten sposób wejściowa względna kolejność liczb

zostanie zachowana.

background image

35

 Następnie wyciągamy elementy z

kubełka i układamy w ciąg. Ważne jest

aby wyciągać je począwszy od kubełka

zerowego aż po kubełek dziewiąty.

 Uzyskany ciąg liczb znów rozrzucamy do

kubełków, ale już względem kolejnej

cyfry (dziesiątek).

 Operacje powtarzamy k razy (k to ilość

cyfr w najdłuższej liczbie).

background image

36

Przykład - ciąg liczb: 436,

124, 068, 348, 741, 041, 002, 675,

943, 179. Krok 1 – cyfra jedności.

background image

37

Krok 2: Cyfra dziesiątek

background image

38

Krok 3: Cyfra setek

background image

39

 Dla niewielkich zbiorów można wykorzystać

do zaimplementowania kolejki zrealizowane

na tablicy statycznej, gdyż przyspiesza ona

szybkość wykonywania.

 W tego typu implementacji nie jest

marnowany czas na operacje związane z

tworzeniem i destrukcją kolejek – raz

utworzone kolejki pozostają. Wykonywane

są tylko operacje związane z przenoszeniem

przenoszeniem danych między kolejkami.

background image

40

 Ta wersja nie sprawdza się w przypadku

dużych ciągów elementów, gdyż
niezbędne jest k (ilość pozycji w
elemencie – np. cyfr) tablic o rozmiarze n
(ilość elementów) oraz tablica wejściowa z
danymi.

 Złożoność tego algorytmu jest rzędu O(n)

(podobnie jak sortowania przez zliczanie).


Document Outline


Wyszukiwarka

Podobne podstrony:
ASD w3
nw asd w3
Systemy Bezprzewodowe W3
Gospodarka W3
AM1 w3
ASD od z Sawanta II Wykład17 6
w3 recykling tworzyw sztucznych
Finansowanie W3
W2 i W3
so w3
UE W3 cut
W3 Elastycznosc popytu i podazy
reprod w3 2008

więcej podobnych podstron