Výběr pivota
Víme jak funguje quicksort a taky si můžeme snadno ověřit, že by bylo ideální jako pivota vybírat medián. Každé rekurzivní volání quicksortu by potom dostalo ke zpracování přibližně poloviční díl.
Výpočet mediánu
Jak ale nalézt medián abychom se moc "nenadřeli"?
Rekurzivní algoritmus, který byl představen na cvičení je znám už dlouho. Na cvičení jsme programovali funkci, která nalezne medián v posloupnosti 5 prvků.
Mergesort
Další z řady třídících algoritmů. Tento rekurzivní algoritmus jsme si vyzkoušeli na vlastní kůži. Pseudokód:
mergesort(L,R,A) A - vstupni posloupnost L - levy index trideneho useku R - pravy index trideneho useku if L+1 = R then // trivialni pripad dvouprvkove posloupnosti if A[L] >= A[R] then prohod(A[L],A[R]) exit if L < R then M:= (R + L) div 2 // index poloviny puvodniho useku mergesort(L,M,A) mergesort(M+1,R,A) merge(L,M,R,A) // slej oba useky a vysledek zapis zpet do A
Procedura merge přitom vypadá takto:
merge(L,M,R,A) B - pomocne pole delky (R-L) [L,M] - prvni usek [M+1,R] - druhy usek b:=1 i:=L j:=M+1 // pomocne indexy while (i <= M) or (j <= R) do // existuje nezpracovany prvek if (i <= M) and (j <= R) then // oba useky neprazdne if A[i] <= A[j] then B[b]:=A[i] inc(i) else B[b]:=A[j] inc(j) inc(b) if (i > M) then // prvni usek prazdny B[b]:=A[j] // dojizdime druhy usek inc(j) inc(b) if (j > R) then // druhy usek prazdny B[b]:=A[i] // dojizdime prvni usek inc(i) inc(b)
Vnější třídění
Pokud máme za úkol setřídit data, která se nám nevejdou do RAM, musíme využít pevný disk, k ukládání mezivýsledků.
Základní postup (idea) jak to udělat je následující:
- 1) načteme do paměti kus vstupních posloupnosti
- 2) setřídíme ve vnitřní paměti co máme načteno
- 3) uložíme na disk setříděný úsek
- 4) pokud nejsou zpracována všechna vstupní data do setříděných úseků, vrátíme se do 1)
- 5) slejeme postupně všechny setříděné úseky do jednoho
Na výše uvedeném postupu lze mnohé vylepšit. Například můžeme ke třídění použít haldu a prodloužit tak vzniklé předtříděné úseky z bodu 3). Nebo můžeme slévat víc souborů najednou - to si můžeme představit jako víc front, z jejichž začátků vždy vybíráme ten nejmenší prvek.
Domácí úkol
V CodExu je zadána uloha Dodavatel mřížek za 20 bodů.