Upload
others
View
3
Download
0
Embed Size (px)
Citation preview
10. Előadás
Beszúró rendezés Használjuk a kupacokat rendezésre!
Szúrd be az elemeket egy kupacba!
Amíg a sor ki nem ürül, vedd ki a kupacból a maximális elemet, és tedd az eredmény (rendezett) sorba!
2
Kupacrendezés Az s sorban lévő elemeket rendezzük a
k kupac segítségével!
3
not s.isempty
not k.isempty
e:=s.out
k.insert(e)
e:=k.delmax
s.in(e)
k.empty
Kupacrendezés A kupacok hatékony rendezőt adnak:
Szúrjunk be minden elemet a kupacban elem, ezekhez kell O(log2n) O(n log n)
sorrendben távolítsuk el az elemeketn elem, ezekhez kell O(log2n) O(n log n)
Összesen O(n log n) ignorálva a 2-es konstanst, stb.
Nézzünk meg egy animációt a kupacrendezésre!
4
Gyorsrendezés (Quicksort) hatékony rendezési algoritmus
C.A.R. Hoare készítette, 1960.
Az „Oszd meg és Uralkodj” algoritmus egy példája
Két fázis
Partíciós fázis
Oszd a munkát két részre!
Rendezési fázis
Uralkodj a részeken!
Gyorsrendezés (Quicksort) Partíció
Válassz egy „strázsát” (pivot)!
Válaszd a strázsa pozícióját olyanra, hogy
minden elem tőle jobbra nagyobb legyen!
minden elem tőle balra kisebb legyen!
< strázsa > strázsastrázsa
Gyorsrendezés (Quicksort) Uralkodj
Alkalmazd ugyanezt az algoritmust mindkét félre!
< strázsa > strázsa
strázsa< p’ p’ > p’ < p” p” > p”
Gyorsrendezés (Quicksort) Implementáció
Oszd meg
Uralkodj
quicksort( void *a, int also, int felso )
{
int pivot;
/* Terminálási feltétel! */
if ( felso > also )
{
pivot = feloszt( a, also, felso );
quicksort( a, also, pivot-1 );
quicksort( a, pivot+1, felso );
}
}
Quicksort - MegosztásEz a példa int-eket
használ az egyszerűség kedvéért!
23 12 15 38 42 18 36 29 27
also felso
Bármelyik elem jó strázsának, válaszd a bal szélsőt!
Quicksort - Megosztás
állítsd be a bal és jobb végét
23 12 15 38 42 18 36 29 27
also felsostr_elem: 23
bal jobb
Quicksort - Megosztás
mozgasd a jelzéseket, míg szembetalálkoznak!
23 12 15 38 42 18 36 29 27
also felsostr_elem: 23
bal jobb
Quicksort - Megosztás
mozgasd a bal jelzőt, míg a str_elem-nél elemekre mutat!
23 12 15 38 42 18 36 29 27
bal jobb
mozgasd a jobb jelzőt hasonlóan
also felsostr_elem: 23
Quicksort - Megosztás
Cseréld ki a str_elem két oldalán rossz sorrendben lévő elemeket!
23 12 15 38 42 18 36 29 27
bal jobb
also felsostr_elem: 23
Quicksort - Megosztás
A „bal” és a „jobb”
szembetalálkoztak, így állj le!
23 12 15 18 42 38 36 29 27
jobbbal
also felsostr_elem: 23
Quicksort - Megosztás
Végül cseréld ki a „str_elem”-et ésa „bal”-nál lévőt
23 12 15 18 42 38 36 29 27
jobbbal
also felsostr_elem: 23
Quicksort - Megosztás
add vissza az „str_elem” pozícióját!
18 12 15 23 42 38 36 29 27
bal
also felsostr_elem: 23
Quicksort – Uralkodj!
18 12 15 23 42 38 36 29 27
rekurzívan rendezi
a bal felét
rekurzívan rendezi a jobb felét
str_elem: 23
Gyorsrendezés algoritmusa
also < felso
q := Feloszt(A, also, felso) SKIPGyorsrendezés (A, also, q-1)Gyorsrendezés (A, q+1, felso)
(A vektorban, also és felso indexek között)
Gyorsrendezés (A, also, felso)
Feloszt(A, also, felso)
str_elem:=A[also]; bal:=also; jobb:=felso;
bal < jobb
A[also]:=A[bal]; A[bal]:= str_elem; return bal;
A[bal]<= str_elem and bal <felso
A[jobb]>= str_elem and jobb >also
bal:= bal+1
jobb:= jobb-1
bal < jobb
Csere(A[bal], A[jobb]) SKIP
Quicksort - Analízis Felosztás vizsgálj meg minden elemet egyszer O(n)
Uralkodás az adatok kétfelé osztása O(log2n)
összesen szorzat O(n log n)
ugyanaz, mint a Heapsort a quicksort általában gyorsabb kevesebb összehasonlítás
De van egy gond …
Quicksort – az igazság! Mi történik, ha az adatok már rendezettek, vagy
majdnem rendezettek?
Azt várnánk, hogy akkor gyorsabb lesz!
Quicksort – az igazság! Rendezett adatok
1 2 3 4 5 6 7 8 9
pivot
< pivot
?
> pivot
Quicksort – az igazság! Rendezett adatok
Minden partíció létrehoz
egy 0 méretű feladatot
és egy n-1 méretűt!
A partíciók száma?
1 2 3 4 5 6 7 8 9
> pivot
2 3 4 5 6 7 8 9
> pivot
pivot
pivot
Quicksort – az igazság! Rendezett adatok
Minden partíció létrehoz egy 0 méretű feladatot
és egy n-1 méretűt!
A partíciók száma? minden n időigénye O(n)
összesen n O(n) vagyis O(n2)
A Quicksort olyan rossz, mint a buborék vagy a beszúrásos rendezés?
1 2 3 4 5 6 7 8 9
> pivot
2 3 4 5 6 7 8 9
> pivot
pivot
pivot
Quicksort – az igazság! A Quicksort O(n log n) viselkedése
a majdnem egyforma partíciókon múlik
O( log n ) van
Átlagosan is majdnem ez a helyzet
és a Quicksort általában O(n log n)
Mit lehet tenni?
Általában semmit
De javíthatjuk az esélyeinket!
Quicksort – A pivot választása Bármelyik strázsa megteszi…
Válasszunk egy másikat …
amikor a partíciók egyformák
akkor O(n log n) időre lesz szükség
1 2 3 4 5 6 7 8 9
pivot
< pivot> pivot
Quicksort – 3-ból a középső pivot Végy 3 pozíciót, és válaszd a középsőt
Pl. első, középső, utolsó
a középső 5
ez a rendezett adatok legjobb felosztása!
O(n log n) idő
Mivel a rendezett (vagy majdnem rendezett) adatok elég gyakoriak, ez egy jó stratégia
különösen, ha azt várjuk, hogy az adataink rendezettek lesznek!
1 2 3 4 5 6 7 8 9
Quicksort – Véletlen pivot Válassz egy strázsát véletlenszerűen
Minden felosztásnál másik pozíciót
Átlagosan a rendezett adatokat jól osztja szét
O(n log n) idő
Kulcs követelmény:
A pivot kiválasztása O(1) idő kell legyen
Quicksort - Garantált O(n log n)? Soha! A tetszőleges pivot választási stratégia vezethet O(n2)
időhöz
Itt a 3-ból a középső kiválasztja a 2-t egy partícióba 1 elem kerül,
a másikba 7
következőnek kiválasztja a 4-t egy partícióba 1 elem kerül,
a másikba 5
1 4 9 6 2 5 7 8 3
1 2 4 9 6 5 7 8 3
Rendezés Buborék, Beszúrásos, Maximumkiválasztásos
O(n2) rendezések
egyszerű kód
kis n-re gyors lehet (rendszer függő)
Quick Sort
Oszd meg és uralkodj
O(n log n)
Quicksort O(n log n) de ….
Lehet O(n2) is
A pivot kiválasztásától függ
3-ból a középső
véletlen pivot
Jobb, de nem garantált
Quicksort használjuk inkább a Heapsort-ot?
A Quicksort általában gyorsabb
kevesebb összehasonlítás és csere
néhány empirikus adat:
Quick Heap Beszúró
Hasonl Csere Hasonl Csere Hasonl Csere
100 712 148 2842 581 2596 899
200 1682 328 9736 9736 10307 3503
500 5102 919 53113 4042 62746 21083
Quicksort Heap Sort Quicksort
általában gyorsabb
néha O(n2) jobb pivot választás csökkenti a valószínűségét
ha átlagosan jó végrehajtási időt akarunk, használjuk ezt
üzleti alkalmazások, információs rendszerek
Heap Sort
általában lassúbb
Garantált O(n log n) … lehet rá építeni, ezt a tervezésben felhasználni!
használjuk például real-time rendszerekhez Az idő egy megszorítás