Algorytmy i struktury danych, AiSD C Wyklad04

background image

Algorytmy i struktury danych

Wykład 4

Rekurencja c.d.

Temat

• Quicksort, czyli ….

• … raz jeszcze o rekurencji… lub

• … kiedy rekurencja bardzo pomaga!

Problem sortowania raz jeszcze…

Specyfikacja

Dane

n, ci

ą

g S=s

1

,…s

n

Wynik

elementy S w porz

ą

dku niemalej

ą

cymi, czyli:

s

i1

s

i2

s

in

.

Dziel i zwyci

ęż

aj

1. Podziel problem na podproblemy tego

samego (lub podobnego) rozmiaru

2. Rozwi

ąż

podproblemy

3. Poł

ą

cz rozwi

ą

zania podproblemów tak,

aby uzyska

ć

rozwi

ą

zanie problemu

głównego

background image

Sortowanie przez scalanie jako

zastosowanie zasady „dziel i rz

ą

d

ź

1. Podziel ci

ą

g wej

ś

ciowy S na dwa

podci

ą

gi S1, S2 (prawie) tej samej

długo

ś

ci

2. Posortuj S1 i S2 osobno (rekurencja)

3. Scal posortowane ci

ą

gi S1 i S2

Quicksort jako inny przykład

zastosowania metody dziel i zwyci

ęż

aj

1. Wybierz element s ci

ą

gu wej

ś

ciowego S i

podziel S na dwa rozł

ą

czne podzbiory:

S1: elementy, które s

ą

s

S2: elementy, które s

ą

s

2. Posortuj S1 i S2 osobno (rekurencja)

3. Zwró

ć

ą

czone ci

ą

gi S1 i S2

Uwaga

ż

ne wyst

ą

pienia elementu s mog

ą

nale

ż

e

ć

do S1 lub S1, ALE

ka

ż

da kopia nale

ż

y tylko do jednego ze zbiorów S1, S2.

Sortowanie dokładniej…

Specyfikacja

Input

l, r – liczby naturalne, a – tablica

sortowanych elementów

Output

elementy z a[lr] w porz

ą

dku

niemalej

ą

cym, czyli

a[l]

a[l+1]

a[r].

Quick sort dokładniej…

Je

ś

li l < r :

1. Wybierz x ze zbioru {a[l], a[l+1],…, a[r]} i

przemie

ść

elementy a[l], a[l+1],…, a[r] tak, aby:

Elementy a[l..s] s

ą

x

Elementy a[s+1…r] s

ą

x

gdzie s jest pewn

ą

liczb

ą

naturaln

ą

tak

ą

,

ż

e l

s

r

2. Posortuj :

a[l...s]

a[s+1…r]

background image

Quick sort jeszcze dokładniej…

qsort

(int a[], int l, int r)

//sortuje a[l…r]

{ int s;

if (l<r) {

s = partition(a,l,r);

qsort

(a, l,

s);

qsort

(a, s+1, r);

}

}

int partition(int a[], int l, int r):

Wybierz x z podtablicy a[l..r]

Poprzemieszczaj elementy tak, aby:

Elementy w a[l..j] s

ą

x

Elementy w a[j+1..r] s

ą

x

Zwró

ć

j jako wynik

Partition: idea

1.

Wybierz x

2.

i

l, j

r

3.

Dopóki i

<

j powtarzaj:

1. Zwiększaj i aż do spełnienia warunku a[i]

x

2. Zmniejszaj j aż do spełnienia warunku a[j]

x

Zamień a[i] z a[j]

4.

Zwróć i

Partition: implementacja

partition(int a[], int l, int r)

{ int x,y;

x=a[l];

l--;

r++;

do

{ while (a[--r]>x);

while (a[++l]<x);

if (l<r) {y=a[r]; a[r]=a[l]; a[l]=y;}

else return r;

} while (1);

}

Quick sort: zło

ż

ono

ść

pami

ę

ciowa

Pami

ęć

:

Tablica zawieraj

ą

ca ci

ą

g wej

ś

ciowy

Stała liczba dodatkowych zmiennych

Pami

ęć

potrzebna do realizacji

rekurencji…?

background image

Quick sort: zło

ż

ono

ść

czasowa

Najgorszy przypadek: procedura partition dzieli
problem na podproblemy o rozmiarach 1 i n – 1:

T(1) = 1

T(n) = T(n-1) + T(1) + n

dla n

>

1

Rozwi

ą

zanie: T(n)

n

2

/2=O(n

2

)

First recursive call

Second recursive call

Cost of partition

Quicksort: zło

ż

ono

ść

czasowa

„Zamierzona” sytuacja: procedura partition dzieli
problem rozmiaru n na dwa podproblemy
rozmiaru n/2:

T(1) = 1

T(n) = T(n/2) + T(n/2) + n

dla n

>

1

Rozwi

ą

zanie: T(n) = O(n log n)

Pierwsze wywoł. rek.

Koszt partition

Drugie wywoł. rek.

Quicksort: zło

ż

ono

ść

czasowa

W praktyce: quicksort jest najszybszym algorytmem

sortowania.

Pyt.:

Jaki czas preferujesz n

2

czy n log n?

Uwagi:

Mo

ż

liwe jest uzyskanie czasu O(n log n) w

najgorszym przypadku (korzystamy z algorytmu
liniowego szukaj

ą

cego mediany)

Wiadomo,

ż

e

ś

redni czas działania Quicksort

jest O(n log n)


Wyszukiwarka

Podobne podstrony:

więcej podobnych podstron