Jednoduché implementácie prioritnej fronty

Prioritná fronta sa dá implementovať rôzne. Najjednoduchším spôsobom je samozrejme pamätať si aktuálnu množinu prvkov a ich priorít v obyčajnom poli. (Prípadne môžeme použiť pole premennej veľkosti, ako napr. vector v C++.) Pri takejto implementácii vieme operáciu push spraviť v konštantnom čase. Problém však nastáva pri operácii pop: aby sme našli prvok s najväčšou prioritou, potrebujeme prejsť a skontrolovať všetky prvky v poli. Táto operácia teda bude mať až lineárnu časovú zložitosť. Ak by sme teda mali postupnosť $n$ operácií push a $n$ operácií pop v nejakom neznámom poradí, môže jej spracovanie dokopy vyžadovať až $O(n^2)$ krokov.

Podobne zlý je aj opačný extrém: udržiavať si poprvky v poli usporiadanom podľa priority (tak, aby prvok, ktorý chceme najskôr spracovať, bol na konci poľa). Tentokrát vieme operáciu pop robiť v konštantnom čase, no platíme za to tým, že pri každej operácii push musíme nájsť správne miesto, kam do poľa patrí nový prvok, a následne v lineárnom čase prvky poľa poposúvať, aby sme na nový prvok mali miesto.

Hľadáme teda nejaký "trade-off" -- nejaké riešenie, ktoré by bolo akoby na polceste medzi vyššie popísanými dvoma riešeniami. Jedným takýmto riešením je použiť na implementáciu prioritnej fronty vyvažovaný binárny strom (ak ste o takom niečom už počuli), v ktorého vrcholoch si budeme jednotlivé prvky pamätať usporiadané podľa priority. Do takéhoto stromu obsahujúceho $n$ prvkov vieme v čase $O(\log(n))$, aj vložiť nový prvok, aj nájsť a odstrániť z neho maximum.

Takéto riešenie je však zbytočne zložité na implementáciu. V tomto texte si ukážeme, ako tie isté časové zložitosti dosiahnuť omnoho jednoduchším programom.