FRONTA Frnta je datvá struktura pdbná zásbníku, avšak její vnitřní rganizace je dlišná. Prvky d frnty vkládáme na jedné straně (na knci) a ubíráme na straně druhé (na začátku). Ve frntě jsu tyt prvky ulženy v přadí, ve kterém byly d frnty vkládány, tudíž při debírání tyt prvky debíráme ve stejném přadí, v jakém jsme je vlžili. Pdbně jak u zásbníku lze prvek z frnty vyjmut puze za takvé pdmínky, že je na řadě. Avšak jeh hdntu můžeme přečíst kdykliv. Výraz frnta nemusí být vždy přesný. Krmě anglickéh Queue se můžete čast setkat s výrazem FIFO, cž je zkratka anglickéh značení First In, First Out (první dvnitř, první ven). Frnta v peračních systémech pr meziprcesvu kmunikaci se také nazývá rura (anglicky pipe). Jak takvá frnta vypadá v praxi můžete vidět na brázku níže: Obr. 1: Schéma frnty Jak se p čase dzvíme, existuje také cyklická frnta. Ta vypadá zhruba takt: Obr. 2: Kruhvá frnta
Frnta s priritami Pririta prvku je funkce hdnty v prvku ulžené. Frnta s priritami (s předbíháním) se liší d klasické frnty tím, že prvky sice ukládáme v přadí, ve kterém přišly, vybíráme je ale v přadí závislém na jejich priritě, tzn. nejprve prvek s nejvyšší priritu. Pririty lze uplatňvat i při vkládání prvků d frnty. Frnty s priritami se avšak bvykle implementují pmcí seznamů. Kruhvá frnta Kruhvá frnta (viz. Obr. č. 2) představuje jednu z bvyklých implementací frnty. Vezmeme v ptaz ple Q [0,,n-1] a budeme s ním zacházet, jak kdyby byl kruhvé, tedy kdyby p prvku Q [n-1] následval prvek Q [0]. Pr bsluhu kruhvé frnty ptřebujeme většinu ukazatele, např. vrch a knec, kde ukazatel vrch ukazuje na začátek frnty a knec na knec frnty. Při každé peraci vkládání neb výběru z kruhvé frnty kntrlujeme, zda náhdu nenastala rvnst, kdy vrch=knec. Nastane-li tat situace p výběru z frnty, znamená t, že frnta je prázdná. Nastane-li tat rvnst p vlžení nvéh prvku, znamená t, že frnta je již plná. Kruhvá frnta se většinu implementuje pmcí cyklickéh ple. Cyklické ple Již známe klasické jednrzměrné a dvurzměrné ple, jakžt skupinu dat stejnéh typu, která je určena hrní a dlní mezí. Pmcí implementace abstraktníh datvéh typu si však můžeme vytvřit vlastní ple. Ple cyklické, kde hrní a dlní mez budu představvat ukazatelé. Cyklické ple si zaimplementujeme jak typ, a t následvně: type Tple = array[1..20] f integer; //deklarace typu ple var ple: Tple; //glbální deklarace vrch, knec: integer; U frnty řešené cyklickým plem máme vyřešit následující perace: CREATE(Q) - vytvří prázdnu frntu Q FRONT(Q) - vrátí první prvek frnty Q APPEND(x, Q) - vlží prvek x na knec frnty Q SERVE(Q) - vymaže první prvek z Q EMPTY(S) - vrátí TRUE, je-li frnta prázdná, jinak vrátí FALSE Vytvření prázdné frnty - CREATE: Vytvření prázdné frnty je velice jednduchý krk, kdy stačí pmcným ukazatelům vrch a knec přiřadit čísl 1. Tudíž ukazují na stejné míst. prcedure TFrm1.Buttn2Click(Ser: TObject); //vytvření prázdnéh seznamu (CREATE) Mem1.Lines.Add('Ple byl úspěšně vytvřen!');
vrch:=1; knec:=1; Výsledná perace bude na brázku vypadat zhruba takt: Obr. 3: Prázdné ple Vlžení prvku d frnty - APPEND: Před vlžením prvku bychm měli zkntrlvat, zda-li ple není plné. T zjistíme jednduchu pdmínku. V případě, že ukazatel knec je různý d 1, a zárveň se rvná vrch-1, je ple plné. V tmt případě jsu tyt ukazatele hned vedle sebe a v pli již není míst. Pkud příkaz za pdmínku nebude vyknán, stačí si věřit, zda je knec různý d 20 a přidat prvek d frnty. Nesmíme však zapmenut přičíst k prměnné knec 1, aby se nám ukazatel psunul. V případě, že se vrch rvná 1, je ple pět plné a prvek se nepřidá. V pačném případě stačí ukazatel knec psunut na pzici 1 a prvek přidat. Buttn7Click(Ser); značuje prceduru výpisu. prcedure TFrm1.Buttn3Click(Ser: TObject); //přidání nvéh prvku (APPEND) if (knec<>1) and (knec=vrch-1) then Mem1.Lines.Add('Ple je bhužel plné, prvek nebyl vlžen...') //stav kdy je ple plné if knec<>20 then ple[knec]:=strtint(edit1.text); //nrmální stav knec:=knec+1; Buttn7Click(Ser); if vrch=1 then Mem1.Lines.Add('Ple je bhužel plné, prvek nebyl vlžen...') //pět stav kdy je ple plné ple[knec]:=strtint(edit1.text); knec:=1; Buttn7Click(Ser);
Odebrání prvku z frnty - SERVE: T, že při vytvření prázdnéh ple ukazuje prměnná vrch a knec na stejné míst již víme. Tht jevu využijeme při peraci SERVE, pkud je ttiž frnta prázdná, není c mazat. Jestliže je ukazatel vrch 20, stačí tent ukazatel psunut na hdntu 1. V případě, že by byl různý d 20, stačí prměnnu zvýšit (inkrementvat) 1. Některým by mhl vadit, že v určitých místech ple zůstaly staré hdnty. Prt si d těcht míst můžete vlžit například čísl 0. prcedure TFrm1.Buttn4Click(Ser: TObject); //debrání prvku (SERVE) if vrch=knec then Mem1.Lines.Add('Ple je prázdné, není c debrat...'); if vrch=20 then vrch:=1; Buttn7Click(Ser); vrch:=vrch+1; Buttn7Click(Ser); Operace, která vrátí první prvek frnty - FRONT: U tét perace stačí d kmpnenty Mem vypsat prvek z ple, na který právě ukazuje pmcná prměnná vrch. prcedure TFrm1.Buttn5Click(Ser: TObject); //vrátí první prvek frnty (FRONT) Mem1.Lines.Add(IntTStr(ple[vrch])); Operace která vrátí TRUE, je-li frnta prázdná, jinak vrátí FALSE - EMPTY: U tét perace si vytvříme funkci, jejímž výsledkem bude true neb false, typu blean. Jestli je ple prázdné zjistíme jednduše pdle th, zda-li se vrch=knec. functin EMPTY: blean; if vrch=knec then result:=true result:=false; prcedure TFrm1.Buttn6Click(Ser: TObject); //vrátí TRUE, je-li frnta prázdná (EMPTY) if EMPTY=true then Mem1.Lines.Add('Ple je prázdné...')
Mem1.Lines.Add('Ple bsahuje prvky...'); Výpis frnty - PRINT: Pr výpis si již budeme muset zadeklarvat pmcnu prměnnu pm, d které se bude ukládat aktuální stav prměnné vrch. Zapíšeme pdmínku while, která vytvří smyčku, kde je knec různý d pm (vrch). Na knci tét smyčky pmcnu prměnnu zvyšujeme 1, v případě, že se nenacházíme na hraně ple 20 a 1, viz. Obr. č. 4. prcedure TFrm1.Buttn7Click(Ser: TObject); //vypíše celý seznam d MemBxu (PRINT) var pm: integer; pm:=vrch; while knec<>pm d Mem1.Lines.Add(IntTStr(ple[pm])); if pm=20 then pm:=1 pm:=pm+1; Obr. 4: Hrana cyklickéh ple