4 sortowanie

background image

1

Wykład 4

Sortowanie

background image

2

Sortowanie - zadanie

Definicja (dla liczb):

wejście: ciąg n liczb A = (a

1

, a

2

, …, a

n

)

wyjście: permutacja (a

1

,…, a’

n

) taka, że a’

1

≤ … ≤ a’

n

Po co sortować?

– Podstawowy problem dla algorytmiki
– Wiele algorytmów wykorzystuje sortowanie jako procedurę

pomocniczą

– Pozwala pokazać wiele technik
– Dobrze zbadane (czas)

background image

3

Sortowanie – taksonomia

Wewnętrzne i zewnętrzne

– Zależnie od miejsca przechowywania zbioru: (RAM czy dysk)

Sortowanie tablic i sortowanie list łączonych

– zależnie od struktury danych (pliku);
– różny sposób dostępu (bezpośredni dla tablicy, sekwencyjny dla listy).

„W miejscu” lub nie

– Nie wymaga dodatkowej pamięci

Stabilne i niestabilne

– Kolejność elementów o tych samych wartościach klucza nie zmienia

się. Inaczej kolejne sortowanie dla złożonych obiektów nie psuje
efektów poprzedniego sortowania.

Bezpośrednie i pośrednie

– zależnie od tego przemieszczamy całe obiekty, czy tylko wskaźniki

(indeksy) do nich

background image

4

Zestawienie czasów działania

Przez wybór:

O(N

2

) zawsze

Bąbelkowe:

O(N

2

) najgorszy przypadek; O(N)

najlepszy przyp.

Wstawianie:

O(N

2

) średnio; O(N) najlepszy przypadek

Shellsort: O(N

4/3

)

Heapsort: O(NlogN) zawsze
Mergesort: O(NlogN) zawsze
Quicksort: O(NlogN) średnio; O(N

2

) najgorszy przypadek

Zliczanie: O(N) zawsze
Radix sort: O(N) zawsze

zewnętrzne:

O(b logb)) dla pliku o b „stronach”.

background image

5

Sortowanie przez wybór – pomysł

Znajdujemy najmniejszy element ciągu i zamieniamy go

z pierwszym elementem. Powtarzamy to dla podciągu
bez pierwszego elementu, itd.

Znajdź minimum i zamień
z pierwszym elementem

X

X

background image

6

Sortowanie przez wybór – pseudokod

Selection_Sort(int A)
1 for i ← 1 to length[A]
2 do min ← i;
3

for j i+1 to length[A]

4 do if A[j] < A[min] then min ← j;
5 Exchange A[min] ↔ A[i]

background image

7

ciąg: EASYQUESTION - rozmiar 12 znaków

#porównań #zamian

EASYQUESTION

A

ESYQUESTION

11

1

AE

SYQUESTION

10

1

AEE

YQUSSTION

9

1

AEEI

QUSSTYON

8

1

AEEIN

USSTYOQ

7

1

AEEINO

SSTYUQ

6

1

AEEINOQ

STYUS

5

1

AEEINOQS

TYUS

4

1

AEEINOQSS

YUT

3

1

AEEINOQSST

UY

2

1

AEEINOQSSTU

Y

1

1

Razem

66 11


1

2

3

4

5

6

7

8

9
1
0
1
1

Sortowanie przez wybór – przykład

iteracj
a

background image

8

Sortowanie przez wybór – czas działania

Zależność od danych wejściowych:

– Ilość przebiegów: nie (zawsze N-1)
– Ilość porównań: nie
– Ilość zamian: nie

O(N

2

) zawsze (bez znaczenia jaki jest układ elementów w

danych – ważna tylko ilość)

background image

9

Sortowanie bąbelkowe (przez zamianę)

Przechodzimy przez ciąg od jego końca, porównując sąsiadujące

elementy i ewentualnie zamieniając je miejscami. Powtarzamy te
procedurę aż do uporządkowania całego ciągu.

– Po pierwszym przejściu element minimalny znajduje się na początku – a[0],

po drugim na drugim miejscu znajduje się drugi co do wielkości – a[1], po itd.

Porównanie do
wypływających bąbelków –
stąd nazwa

.

background image

10

Sortowanie bąbelkowe – pseudokod

BUBBLE_SORT(A)
1 for i ← 1 to length[A]
2 do for j length[A] downto i + 1
3 do if A[j] < A[j - 1]
4 then exchange A[j] ↔ A[j -

1]

background image

11

Ciąg: EASYQUESTION, (12 znaków)

porównań

zamian

EASYQUESTION

(najgorszy przyp)

A

EESYQUISTNO

11 (11) 8 (11)

AE

EISYQUNSTO

10 (10) 6 (10)

AEE

INSYQUOST

9 (9) 6 (9)

AEEI

NOSYQUST

8 (8) 4 (8)

AEEIN

OQSYSUT

7 (7) 3 (7)

AEEINO

QSSYTU

6 (6) 2 (6)

AEEINOQ

SSTYU

5 (5) 1 (5)

AEEINOQS

STUY

4 (4) 1 (4)

AEEINOQS

STUY

3 (3)

0

(3)

(2) (2)

(1)

(1)

razem 63 (66)

31 (66)

iteracja

1
2
3
4
5
6
7
8
9

Sortowanie bąbelkowe – przykład

background image

12

Sortowanie bąbelkowe – czas wykonania

Zależność od danych wejściowych:

– Ilość potrzebnych przejść: tak

– Ilość porównań w jednym przejściu: nie

– Ilość zamian: tak

Najgorszy przypadek: O(N

2

)

– Dane odwrotnie posortowane, np.: JIHGFEDCBA.

– N-1 przejść

– (N-1)N/2 porównań i (N-1)N/2 zamian

Najlepszy przypadek: O(N)

– Jeśli elementy są już posortowane, np.: ABCDEFGHIJ.

– Tylko jedno przejście. Stąd mamy N-1 porównań i 0 zamian.

background image

13

Sortowanie przez wstawianie – pomysł

Dla każdego elementu ciągu (od lewej do prawej),

wstawiamy go we właściwe miejsce ciągu elementów
poprzedzających go (już posortowanych).

background image

14

Sortowanie przez wstawianie – pseudokod

INSERTION_SORT(A)
1 for j ← 2 to length[A]
2 do key A[j]
3 i j-1
4 while i>0 and A[i]>key
5 do A[i+1] ← A[i]
6 ii-1
7 A[i+1] ← key

background image

15

Ciąg: EASYQUESTION, (12 znaków)

porównań

zamian

(najgorszy przyp.)

E

ASYQUESTION

A

E

SYQUESTION

1 (1)

1 (1)

AE

S

YQUESTION

1 (2)

0 (2)

AES

Y

QUESTION

1 (3)

0 (3)

AE

Q

SY

UESTION

3 (4)

2 (4)

AEQS

U

Y

ESTION

2 (5)

1 (5)

AE

E

QSUY

STION

5 (6)

4 (6)

AEEQS

S

UY

TION

3 (7)

2 (7)

AEEQSS

T

UY

ION

3 (8)

2 (8)

AEE

I

QSSTUY

ON

7 (9)

6 (9)

AEEI

O

QSSTUY

N

7 (10)

6 (10)

AEEI

N

OQSSTUY

8 (11)

7 (11)

razem

41 (66) 31 (66)

iteracja

1
2
3
4
5
6
7
8
9
10
11

Sortowanie przez wstawianie – przykład

background image

16

Sortowanie przez wstawianie – czas
działania

Zależność od danych wejściowych:

– Ilość iteracji: nie (zawsze N-1)
– Ilość porównań: tak
– Ilość zamian: tak

Najgorszy przypadek: O(N

2

)

– Elementy odwrotnie posortowane np.: JIHGFEDCBA.
– (N-1)N/2 porównań i (N-1)N/2 zamian.

Najlepszy przypadek: O(N)

– Elementy już posortowane np.: ABCDEFGHIJ.
– Jedno porównanie i 0 zamian w każdej iteracji. Razem, N-1

porównań i brak zamian.

background image

17

Shellsort – pomysł

Modyfikacja (rozszerzona wersja) sortowania przez

wstawianie

Dążymy do zmniejszenia ilości zamian – albo ciągi

krótkie, albo lepsze („bliższe” posortowania).

Shellsort wykonuje sortowanie podciągów:

– Wybieramy ciąg liczb (zwany ciągiem przyrostów) h

t

, …

,

h

2

, h

1

;

– h

1

=1; h

t

> … > h

2

>h

1

;

– Sortujemy ciągi elementów odległych o h

t

, h

t-1

, h

t-2

,…,h

1

.

background image

18

Shellsort – kod w C

void shellsort (int[ ] a, int n)

{

int i, j, k, h, v;

int[ ] cols = {1391376, 463792, 198768, 86961, 33936, 13776, 4592,

1968, 861, 336, 112, 48, 21, 7, 3, 1}

for (k=0; k<16; k++)

{

h=cols[k];

for (i=h; i<n; i++)

{

v=a[i];

j=i;

while (j>=h && a[j-h]>v)

{

a[j]=a[j-

h];

j=j-h;

}

a[j]=v;

}

}

}

background image

19

Shellsort – przykład

ciąg: EASYQUESTION (12 znaków)
ciąg przyrostów 4, 1.

porównań zamian

EASYQUESTION

E

ASY

Q

UES

T

ION

2

0

E

A

SY

Q

I

ES

T

U

ON

3

1

E

A

E

Y

Q

I

O

S

T

U

S

N

3

2

E

A

E

N

Q

I

O

S

T

U

S

Y

3

3

Razem w tej fazie

11

6

faza 1: przyrost = 4

background image

20

Shellsort – przykład

porównań zamian

EAENQIOSTUSY

AE

ENQIOSTUSY

1

1

AEE

NQIOSTUSY

1

0

AEEN

QIOSTUSY

1

0

AEENQ

IOSTUSY

1

0

AEEINQ

OSTUSY

3

2

AEEINOQ

STUSY

2

1

AEEINOQS

TUSY

1

0

AEEINOQST

USY

1

0

AEEINOQSTU

SY

1

0

AEEINOQSSTU

Y

3

2

AEEINOQSSTUY

1

0

Razem w tej fazie

16

6

faza 2: przyrost= 1

background image

21

Shellsort – przykład

Razem 27 porównań i 12 zamian.
Dla sortowania przez wstawiania odpowiednio 41 i

31 !!!

– Polepszenie dostajemy przez wstępne posortowanie,

krótkich podciągów

Zwykle stosuje się ciągi przyrostów o więcej niż 2

elementach.

background image

22

Shellsort – czas działania

Nie ma możliwości przeprowadzenie dokładnej analizy dla

przypadki ogólnego (wyniki są oparte o badania
empiryczne).

Wybór ciągu przyrostów ma zasadniczy wpływ na czas

sortowania.

– Dla ciągu podanego przez Shell’a: O(N

2

)

• I

max

= Floor(N/2), I

k

= Floor(I

k+1

/2).

• np N=64:1, 2, 4, 8, 16, 32

– Dla ciągu podanego przez Knuth’a: O(N

3/2

)

• I

1

=1, I

k+1

= 1+3*I

k

.

• 1, 4, 13, 40, 121, 364, …

background image

23

Mergesort – pomysł

Dzielimy ciąg na podciągi, sortujemy te podciągi, a

następnie łączymy zachowując porządek.

– Przykład algorytmu typu „dziel i zwyciężaj”.
– Potrzeba dodatkowego miejsca dla tych podciągów – nie

jest to sortowanie „w miejscu”.

• Można realizować ten proces „w miejscu”, ale rośnie

stopień komplikacji.

background image

24

Mergesort – przykład

ciąg: EASYQUESTION (12 znaków)

EASYQUESTION

EASYQU

ESTION

EAS

YQU

EST

ION

E

AS

Y

QU

E ST I ON

A S

Q U

S T

O N

podział

background image

25

Mergesort – przykład

AEEINOQSSTUY

AEQSUY

EINOST

AES

QUY

EST

INO

E

AS

Y

QU

E

ST

I

NO

A S

Q U

S T

O N

łaczenie

A E S

Q U Y

C1

C2

C3

background image

26

Mergesort - pseudokod

MERGE-SORT(A, p, r)

1 if p < r

2

then q ← ⌊(p + r)/2⌋

3

MERGE-SORT(A, p, q)

4

MERGE-SORT(A, q + 1, r)

5

MERGE(A, p, q, r)

background image

27

Mergesort - pseudokod

MERGE(A, p, q, r)
1 n1 ← q - p + 1
2 n2 ← r - q
3 create arrays L[1 ..n1 + 1] and R[1 ..n2 +

1]

4 for i ← 1 to n1
5 do L[i] ← A[p + i - 1]
6 for j ← 1 to n2
7 do R[j] ← A[q + j]
8 L[n1 + 1] ← ∞
9 R[n2 + 1] ← ∞
10 i ← 1
11 j ← 1
12 for k p to r
13 do if L[i] ≤ R[j]
14

then A[k] ← L[i]

15

i i + 1

16 else A[k] ← R[j]
17 j j + 1

background image

28

Sortowanie w czasie

liniowym

background image

29

Przegląd

Czy możliwe jest sortowanie w czasie lepszym niż dla

metod porównujących elementy (poprzednio – najlepsze
algorytmy dawały czas O(NlogN))?

Algorytmy o liniowym czasie działania:

– Przez zliczanie (Counting-Sort)
– Radix-Sort
– Kubełkowe (Bucket-sort)

Potrzeba dodatkowych założeń!

background image

30

Sortowanie o czasie liniowym

Możliwe przy dodatkowych informacjach (założeniach) o

danych wejściowych.

Przykłady takich założeń:

– Dane są liczbami całkowitymi z przedziału [0..k] i k = O(n).
– Dane są liczbami wymiernymi z przedziału [0,1) o rozkładzie

jednostajnym na tym przedziale

Trzy algorytmy:

– Counting-Sort
– Radix-Sort
– Bucket-Sort

background image

31

Zliczanie (Counting sort)

wejście: n liczb całkowitych z przedziału [0..k], dla k = O(n).

pomysł: dla każdego elementu wejścia x określamy jego

pozycje (rank): ilość elementów mniejszych od x.

jeśli znamy pozycję elementu – umieszczamy go na r+1

miejscu ciągu

przykład: jeśli wiemy, że w ciągu jest 6 elementów mniejszych

od 17, to 17 znajdzie się na 7 miejscu w ciągu wynikowym.

powtórzenia: jeśli mamy kilka równych elementów

umieszczamy je kolejno poczynając od indeksu pozycja

background image

32

Zliczanie (Counting sort)

1

3

2

4 5

Jeśli nie ma powtórzeń i n = k,
Rank
[A[i]] = A[i] i B[Rank[A[i]]
A[i]

Dla każdego A[i], liczymy

elementy ≤ od niego. Daje to

rank (pozycję) elementu

4

1

2

5

A =

B =

Rank =

4

3

5

2

1

3

background image

33

Zliczanie (Counting sort)

5

1

2

3

A =

3

2

4

Rank =

Jeśli nie ma powtórzeń i n <
k

,

Niektóre komórki tablicy
rank pozostają
niewykorzystane, ale
algorytm działa.

B =

5

2

1

1

3

background image

34

Zliczanie (Counting sort)

4

1

2

2

A =

1

4

3

5

Rank =

Jeśli n > k i mamy
powtórzenia,

umieszczamy na wyjściu
powtarzające się elementy
w takiej kolejności, w jakiej
występowały w oryginalnym
ciągu (stabilność)

B =

3

3 4

2

1

2

2

background image

35

Zliczanie (Counting sort)

Counting-Sort(A, B, k)
1.

for i  0 to k

2.

do C[i]  0

3.

for j 1 to length[A]

4.

do C[A[j]]  C[A[j]] +1

5.

/* C zawiera ilości elementów równych i

6.

for i  1 to k

7.

do C[i]  C[i] + C[i –1]

8.

/* C zawiera ilości elementów ≤ i

9.

for jlength[A] downto 1

10.

do B[C[A[j]]]  A[j]

11.

C[A[j]]  C[A[j]] – 1

A[1..n] – tablica wejściowa
B
[1..n] – tablica wyjściowa
C
[0..k] – pomocnicza tablica (do zliczania)

background image

36

Sortowanie przez zliczanie – przykład (1)

n = 8
k = 6

B[C[A[j]]]  A[j]

C[A[j]]  C[A[j]] – 1

po p. 11

C[A[j]]  C[A[j]] +1

po p.4

C =

0 1 2 3 4 5

2

2

0

3 0 1

2

3

5

0 2 3 0 3

A =

1 2 3 4 5 6 7 8

2

4

2

7 7 8

C =

0 1 2 3 4 5

C[i]  C[i] + C[i –1]

po p. 7

2

4

2

7 8

C =

0 1 2 3 4 5

7

1 2 3 4 5 6 7 8

B =

3

6

background image

37

Sortowanie przez zliczanie – przykład (2)

0

3

B =

2

4

2

6 7 8

C =

0 1 2 3 4 5

1 2 3 4 5 6 7 8

2

3

5

0 2 3 0 3

A =

1 2 3 4 5 6 7 8

2

4

2

6 7 8

C =

0 1 2 3 4 5

1

background image

38

Sortowanie przez zliczanie – przykład (3)

0

3

B =

1

4

2

6 7 8

C =

0 1 2 3 4 5

1 2 3 4 5 6 7 8

2

3

5

0 2 3 0 3

A =

1 2 3 4 5 6 7 8

2

4

2

6 7 8

C =

0 1 2 3 4 5

3

5

background image

39

Counting sort – czas działania

 Pętla for w p.1-2 zajmuje czas Θ(k)
 Pętla for w p.3-4 zajmuje czas Θ(n)
 Pętla for w p.6-7 zajmuje czas Θ(k)
 Pętla for w p.9-11 zajmuje czas Θ(n)
 Stąd dostajemy łączny czas Θ(n+k)
 Ponieważ k = O(n), T(n) = Θ(n) algorytm jest

optymalny!!

Konieczne jest założenie k = O(n). Jeśli k >> n to

potrzeba to potrzeba dużej ilości pamięci.

Nie jest to sortowanie „w miejscu”.

background image

40

Radix sort – sortowanie pozycyjne

wejście: n liczb całkowitych, d-cyfrowych, łańcuchów o d-

pozycjach

pomysł: zajmować się tylko jedną z cyfr (sortować

względem kolejnych pozycji – cyfr/znaków). Zaczynamy
od najmniej znaczącej
cyfry/znaku, potem kolejne pozycje
(cyfry/znaki), aż do najbardziej znaczącej
. Musimy
stosować metodą stabilną. Ponieważ zbiór możliwych
wartości jest mały (cyfry – 0-9, znaki ‘a’-’z’) możemy
zastosować metodę zliczania, o czasie O(n)

Po zakończeniu ciąg będzie posortowany!!

background image

41

Radix sort – przykład

7 2

0

3 2

9
4 3

6
8 3

9
3 5

5
4 5

7
6 5

7

3 2

9

4 5

7
6 5

7
8 3

9
4 3

6
7 2

0
3 5

5

7 2

0

3 5

5
4 3

6
4 5

7
6 5

7
3 2

9
8 3

9

3 2

9

3 5

5
4 3

6
4 5

7
6 5

7
7 2

0
8 3

9

background image

42

Radix-Sort – pseudokod

Radix-Sort(A, d)
1. for i  1 to d
2. do zastosuj stabilną metodę sortowania do cyfry d dla

tablicy A

uwagi:

złożoność: T(n) = Θ(d(n+k))  Θ(n) dla stałego d i k = O(1)

wartości cyfr/znaków są z zakresu [0..k –1] dla k = O(1)

Metoda stosowana dla poszczególnych pozycji musi być
stabilna!

background image

43

Sortowanie kubełkowe – Bucket sort

wejście: n liczb rzeczywistych z przedziału [0..1) ważne jest,

aby były równomiernie rozłożone (każda wartość równie
prawdopodobna)

pomysł: dzielimy przedział [0..1) na n podprzedziałów

(„kubełków”):0, 1/n, 2/n. … (n–1)/n. Elementy do
odpowiednich kubełków, a

i

: 1/ia

i

≤ 1/(i+1). Ponieważ

rozkład jest równomierny to w żadnym z przedziałów nie
powinno znaleźć się zbyt wiele wartości. Jeśli wkładamy je
do kubełków zachowując porządek (np. przez wstawianie –
Insertion-Sort), dostaniemy posortowany ciąg.

background image

44

Bucket sort – przykład

.78

.17

.39

.26

.72

.94

. 21

.12

.23

.68

7

6

8

9

5

4

3

2

1

0

.17

.12

.26

.23

.21

.39

.68

.78

.72

.94

.68

.72

.78

.94

.39

.26

.23

.21

.17

.12

background image

45

Bucket-Sort

Bucket-Sort(A)
1.

n  length(A)

2.

for i  0 to n

3.

do wstaw A[i] do listy B[floor(nA[i])]

4.

for i  0 to n –1

5.

do Insertion-Sort(B[i])

6.

Połącz listy B[0], B[1], … B[n –1]

A[i] tablica wejściowa
B
[0], B[1], … B[n –1] lista „kubełków”

background image

46

Bucket-Sort – złożoność czasowa

Wszystkie instrukcje z wyjątkiem 5 (Insertion-Sort) wymagają

czasu O(n), w przypadku pesymistycznym.

W przypadku pesymistycznym, O(n) liczb trafi do jednego

„kubełka” czyli ich sortowanie zajmie czas O(n

2

).

Jednak w średnim przypadku stała ilość elementów wpada do

jednego przedziału – stąd czas średni wyniesie O(n).


Document Outline


Wyszukiwarka

Podobne podstrony:
Sortowanie cz 2 ppt
Sortowanie listów
algorytmy sortowanie
5 sortowanie log
4 Sterowanie sortowaniem RSS 2013
Ściaga sortowania, algorytmy i struktury danych
Sortowanie kilku kolumn jednocześnie, excel
3 Wyklad Sortowanie
linia sortownicza A1
5 Grupowanie i sortowanie
sortowanie, BHP
Sprawozdanie sortowania
Sortowanie bąbelkowe
Programowanie Sortowanie
Sortowanie?nych w tabeli przestawnej
Sortowania
el.cw4 - Obwody trójfazowe2, Politechnika Lubelska, Studia, Studia, Elektrotechnika - laboratorium,
sortowanie przez zliczanie

więcej podobnych podstron