O třídění jako takovém

Pokročilé řadicí algoritmy

SSŠVT


O třídění jako takovém

Úvod

Řadicí (aka třídicí) algoritmy jsou algoritmy, jejichž vstupem je kolekce objektů (např. pole), které lze porovnat, tj. říci, který ze dvou objektů je větší, nebo menší, případně zda jsou (pro dané porovnávací kritérium) stejné.

Výstupem třídicího algoritmu je tatáž kolekce objektů, jejich pořadí je ovšem takové, že např. pro třídění od nejmenšího prvku po největší platí pro každé dva sousední prvky, že prvek s menším indexem je menší nebo roven prvku s větším indexem.

Třídění se hodí pro spoustu životních situací. Stále něco třídíme:


Efektivita

U třídicích algoritmů se sleduje jejich efektivita. Odborně se jedná o tzv. složitost, která vyjadřuje počet základních operací nutných k doběhnutí algoritmu.

Základními operacemi u třídění jsou zejména operace porovnání (comparison) dvou prvků v kolekci, kterou třídíme, a prohození (swap) dvou prvků v kolekci (změna jejich pozic, tedy vlastně indexů).


Pro představu

Například algoritmus Bubble sort, který má složitost O(n2), potřebuje pro setřídění vstupní kolekce o n prvcích n2 operací porovnání a prohození, kde n2 maximálně ještě vynásobíme nějakou konstantou, zde třeba třemi. (Tři operace na jedno prohození - např. porovnání, prohození, posuny indexů.) Máme-li tedy vstupní pole o 32 osobách, které chceme setřídit podle jejich roku narození, potřebujeme v Bubble sortu přibližně 32 x 32 x 3 = 1024 x 3 = 3072 operací pro úspěšné dokončení našeho záměru.

Použijeme-li Merge sort, který má složitost O(n log n), kde logaritmem se většinou míní logaritmus o základu 2, pak na setřídění stejné kolekce 32 osob podle roku narození budeme potřebovat např. pouze 32 x log 32 x 3 = 32 x 5 x 3 = 480 operací.

Kdyby provedení jedné základní operace trvalo přibližně 1 sekundu, trvalo by Bubble sortu setřídění kolekce 32 osob skoro hodinu, kdežto Merge sort by to zvládl asi za 8 minut.


Příklady třídicích algoritmů

Ukážeme si 3 příklady "pomalých" třídicích alogoritmů a 3 příklady efektivních třídicích algoritmů.

Algoritmus Princip Složitost
Bubble sort "Těžší" (větší) prvky probublávají na konec kolekce. O(n2)
Insertion sort V setříděné části kolekce vkládám postupně prvky na jejich "správné" místo. O(n2)
Selection sort Na konec setříděné části kolekce přidám vždy např. minimum z nesetříděné části. O(n2)
Quicksort Vyberu náhodně prvek z kolekce, tzv. pivot, a prvky menší než pivot dám vlevo, větší než pivot vpravo. Pak totéž provedu pro levou a pravou část, mezi nimiž je pivot. O(n log n)
Merge sort Rozdělím kolekci na mini-kolekce s jedním prvkem. Vezmu vždy dvě sousední jednoprvkové kolekce a spojím je do jedné, již setříděné. Pak vezmu výsledné dvouprvkové kolekce a spojuji vždy dvě a dvě stejným způsobem atd. O(n log n)
Heapsort Ze vstupní kolekce vyrobím haldu (heap), kde na dvou menších prvcích musí vždy "sedět" větší prvek. Zbytek je podobný Selection sortu, halda reprezentuje nesetříděnou část kolekce. O(n log n)