You are on page 1of 265
Google This book is provided in digital form with the permission of the rightsholder as part of a Google project to make the world's books discoverable online. The rightsholder has graciously given you the freedom to download all pages of this book. No additional commercial or other uses have been granted Please note that all copyrights remain reserved About Google Books Google's mission is to organize the world’s information and to make it universally accessible and useful. Google Books helps readers discover the world’s books while helping authors and publishers reach new audiences. You can search through the full text of this book on the web at ittp//books.google.com4 Daniel Danciu George Mardale ARTA PROGRAMARII IN JAVA vol II - Algoritmi gsi structuri de date viizessy Google Cuprins 9 Analiza eficientei algoritmilor 10 94 92 93 94 95 Ce este analiza algoritmilor? Notajia asimptotics 9.2.1 O notafie pentrs ordinul de marime al timpului de exe~ ccufie al unui algoritm Tehnici de analiza algoritmilor 9.3.1 Sortarea prin selectie 9.3.2 Sortarea prin inserie 9.33 Tumurile din Hanoi Analiza algoritmilor recursiv 9.4.1 Metoda itera 9.4.2 Inducfia constructiva, 9.4.3 Recurenje liniare omogene 9.44 Recurenje liniare neomogene 9.4.5 Schimbarea variabilei Implementarea algoritmilor Structuri de date 10.1 102 103 104 105 106 Cum implementam structusile de date? Stive Cozi ste inlinjuite Arbor. : 10.5.1 Nogiuni generale 10.52 Arboribinari 10.5.3 Arboribinaride ctutare Tabele de repartizare 10.6.1. Tratarea coliziunilor 3 15 16 18 19 21 2 23 24 28 28 26 26 28 31 33 40 B 45 sl 2 55 65 69 - 83 cura 10.7 Cozi de prioritate 107.1 Ansamble Metoda Backtracking 11.1 Preentare generals 112 Prezentarea metodei 1121 Atribuie si avanseaza 11.22 incercareepuati 1123 Revenire 11.24. Revenire dupa constuirea une slut 11.3 Implementarea metode backtracking 114 Probleme clasicerezolvabile prin backtracking 114.1. Problema gener permutirilor : 114.2. Generarenaranjamentelor ga combinisilor 1143 Problema damelor 114.4 Problema colori hiqilor 12 Divide et impera 12.1 Introducere in recursivitate 12.1.1 Funefii recursive 12.1.2. Recursivitatea nu inseamna recurenyii 12.2 Prezentarea metodei Divide et Impera 12.3 Céutare bina’ 124 Sortarea prin interclasare (MergeSort) 125 Sortarea rapids (QuickSort) 126 B 13 Algoritmi Greedy 13.1 Problema spectacolelor (selectarea activittitor) 13.1.1 Demonstrarea corectitudini algoritmului 13.1.2. Solujia problemei spectacolelor 13.2 Elemente ale strategiei Greedy 13.2.1. Proprictatea de alegere Greedy 13.2.2. Substructura optim’ 13.3 Minimizarea timpului mediu de asteptare 134 Interclasarea optima a mai multor sirusi ordonate 92 108 109 no 14 14 1s 15 7 119 119 124 126 7 437 138 138 43 145 146 149 152 157 167 168 169 im 173 176 176 7 180 4 15 16 Programare dinamici 14.1 Istorie gi descriere 14.2 Primi pasi in programarea dinamici 14.2.1. Probleme de recurensa matematica trata dinamic 14.3 Fundamentare teoreticd 144 Principiul optimalititii .. . . ss. 14.4.1 Metoda “inainte” si metoda “inapoi” . . 14.4.2. Determinarea efectiva a solutiei optime 14.5 Inmultirea unui sir de matrice 14.6 Subgir comun de lungime maxima 14.7 Distanja Levensthein ‘Metoda Branch & bound 15.1. Prezentare general’ 15.1.1 Fundamenteteoretice 15.2. Un exemplu: Puzzle cu 15 elemente 15.2.1. Enunjul problemei 15.2.2. Rezolvarea problemei Metode de elaborare a algoritmilor (sintezi) 16.1 Backiracking 16.2 Divide et impera 16.3 Greedy 1644 Programare dinamict 16.5 Branch & bound cures 186 187 138 188 198 2.201 2204 205 208 215 20 236 236 237 240 240 241 255 255 255 256 256 256 viizessy Google Introducere Nu calcula capacitatea unui pod rnumirind persoance care traverseaz acum rl int “Auziti lao prezentare Oricine a folsit cel pun o data Intemetal sau acitit o revista de specialitate {in domeniul informatici, a auzit ou siguranficuvanal Java". Java reprezinta un limbaj de programare eeat de compania Sun Microsystems in anu 1995, Ini Java fost gndit penta imibunat coninutul paginilor web prin adaiu- garea unui conjnatdinamic: animatie, multimedia etc. In momentul lansirit sale, Java a revolutionat Interetul, deoarece era prima tehnologie care oferea un asfel de contnst. Ultrior au apart si alte tehnologiaseminatoare (cum ar fi Microsoft ActiveX sau Macromedia Shockwave!), dar Java gi-a pistrat immportana deoscbitt pe care a dobindit-o i randul programatorilor. i primal rind datort facilitilor pe care Ie oferea.Incepnd cu anul 1998, cind a apdrut versinmea 2a limbajuui (engl. Java 2 Platform), Java a fost extins, acoperind g tte direct de deavoltre: programaveaaplicafilor enterprise (aplcaii de tip server), precum sia celor adresatedisportivelor eu resurse limita, cum arf telefoane mobile, pager-e sau PDA-uri2. Toate acestea au reprezentat faclitiyi noi adiugatelimbajulu, care a pasta inst si posible de a crea aplicatit standard, de ip aliafilr a inte de comands sau apicait bazate pe GUT! "Gai care wilzecl aides Iteretal sunt probabil big cu contoale ActiveX sa ev ani: ‘mai ash ead papier web. SPDA = Personal Digital Assistant (mci dspoive de eau, de dimension poi mai mac ect sl unui telefon mobi capable fee fait de agen, dat is uleze apical fran ‘mod ela aseminstor cu celal unis PC)-La moment acl exist ml multe pride PDA Pullm-us, pockelPC-u GUT = Graphical User Inrface, itera grafic de comunicare cu uilzatorl, cum sunt in several aplcaile disponiile pe sistomal de operare Microsoft Windows. 7 serRODUCERE Lansarea versiunii 2 a limbajului Java a fost 0 dovada a succesului imens de care s-au bucurat versiunile anterioare ale limbajului, dar gia dezvoltiritimba- jului in sine, a evolugiei sale ascendente din punct de vedere al facilitator pe care le ofer, cat si al performanjelor pe care le realizeazs. Cum este organizata aceasti carte? Avand in vedere popularitatea extraordinari de care se bucurlimbajul Java {in cadrul programatorilor din intreaga lume, am considerat util scrierea unei lucrari in limba romana care si fie accesibili celor care dorese si invefe sau si aprofundeze acest limbaj. Ideea care a stat la baza realizarii acestei c&rji a fost aaceea de a prezenta nu numai limbajul Java in sin, ci si modul in care se imple- ‘menteaza algoritmii gi structure de date fundamentale in Java, elemente care sunt Agadar, cartea nu este 0,3no EN, astfel incat V n> no avem t(n) Sex f(n)} Cualte cuvinte, Of (se cites “ordinul lu") este muljimea tuturos functi- ilor ¢ marginite superior de un multiplu real pozitiv al lui , pentru valori suf- cient de mari ale argumentuluin. Vom conveni s& spunem ed reste in ordinul Jui (sau, echivalent, reste in OG), sau t € O(f) ) chiar si atunci cénd rn) este negativ sau nedefinit pentru anumite valori n < no. {n mod similar, vom vorbi despre ondinul lui f chiar si atunci cand valoarea f(n) este negativa sau nedefnits pentru un num finit de valor ale lui n in acest eaz, vom alege no Suficient de mare, astfl inet pentru n > no acest Inert s8 nw mai apard. De exemplu, vom vorbi despre ordinul lui wlog n , chiar dack pentru n=0 si n=1 functia nu este definté. in loc de t € O(f), uncori este mai convenabil si foosim notaia t(n) € O(f(n)), subinjelegsnd aici in) gif) sunt foneti Fie un algoritm dat si fie o funeyie t : N+ (0,0), astfel inet o anumita implementare a algoritmului s& necesite cel mult s(n) unitaji de timp pentru a rezolva un caz de mirime n, unde n € N. Principiul invarianjei' ne asigura atunei ci orice implementare a algoritmului necesita un timp fn ordinul uit Cu alte cuvinte, acest algoritm necesité un timp in ordinul lif pentru orice funcyie f : N + [0,00) pentas care t € O(f). In particular avem relay £€ O(t) . Vom cia, in general, si g8sim cea mai simplé functe f,astfel init te O(f). Exemplu: Fie functia t(n) = 3n? —9n+13, Pentru n suficient de mare, vom avea relatia t(n) < 4n?. in consecinfa, luand ¢ = 4, putem spune ca t(n) € (O(n?), La fel de bine puteam si spunem ca t(n) € O(13n? — V2n + 12.5), dar pe noi ne intereseaza sa gisim o expresie cat mai simpli, Este adevarata si relatia t(n) € O(n) dar, aga cum vom vedea mai tarziu, suntem interesai de @ margini cat mai strins ordinal de marime al algoritmului, pentru a putea obiectiva cat mai bine durata sa de executic. Proprietajle de baz ale lui O() sunt date ca exerciti (1 - 5) si ar fi reco ‘mandabil si le studiai inainte de a trece mai departe. TAcestpincipu afin cl dood implements df ale aceluasalgvim au dtr, cf ica, deci ol malt panto constanté muipicav. 19 92. NOTATIA ASIMPTOTICA Notatia asimptoticd defineste o relate de ordine pargiald inte functis, prin urmare, inte eficienja relativ’ a diferifilor algoritmi care rezolvé © anumiti problemi. Vom da in continuare o interpretarealgebrici a nota’ asimptotice. Pentru oricare doud functii f,g : N -> 3" definim urmatoarea relayie binark: f < g dack O(f) C O(g). Relatia "< * este o relagie de ordine partial (reflexiva, tranzitiva, antisimetricd) in multimea functilor definite pe N si cu valori in [0, 00) (exercitiul 4). Definim si o relate de echivalenia: f = 9 daca O(f)=0(g). Prin aceasti relate objinem clase de echivalenta, o clasd de echivalenta cuprinzind toate functile care diferd intre ele print-o constant ‘muliplicativa. De exemplu, Ign = In n si avem o clasi de echivalenga a functi- ilor logaritmice, pe care 0 notim generic cu Offog n) . Notand cu O(7) clasa de cchivalent a algoritmilor cu timpul marginit superior de o constanta (cum ar terschimbarea a dow’ numere, sau maximul a trei elemente), ierarhia celor mai cunoscute clase de echivalengi este: 0(2) c O(logn) c O(n) ¢ O(ntogn) ¢ O(n?) ¢ O(n8) ¢ O(2") Aceasti ierarhie corespunde unei clastic a algoritmilor dupa un exteria al performanjei. Pentcu o problem dats, dorim mereu si objinem un algoritm corespunzitor unei clase aflate c&t mai “de jos" (cu timp de execute ct mai mic). Astfl, se considerd a fi © mare realizare dack in locul unui algoritm exponenyial gisim un algoritm potinoma. Exerciiul 5 ne di o metods de simpliticare a calculelorin care apare notaia asimptticd. De exemplu: n+ 4n? + 2n-+7 € O(n? + (4n? + 2n +7) = O(maz(n', An? + 2n +7) = O(n) Ultima egalitate este adevirati chiar dack maz(n®,4n? + 2n +7) # n® pentri 0 0,3ng EN, astfel incat V n> np avem tn) > c+ f(n)} Existd o anumité dualitateintre notajiile O() si Of): pentru dou functi oarecare fg: N > [0, 00), aver F € O(g) daci si numai dact g € Mf) Oestimare foarte precisa atimpului de exccuie se objneatunci end timpul de executie al unui algoritm este limitat atat inferior cat si superior de cate un tulip real pocii al aceleag fet. fn acest scop introducer nota: Of) = OF) NAA) numiti ondinul exact al lui f- Pentru a compara ordinele a doud functii notajia © nu este ini mai putericd decat notaia O, in sensul c& OY)=Ot¢) este echivalent eu O(f) = 0(9). it in care timpal de execuyie al unui algortm depinde simultan dle mai mult parametsi. Aceste situa sunt tipice pentru anumit algoritmi care opereazi cu grafuri si la care timpul depinde atit de numirul de varfuri ct si de numal de muchii. Notajiaasimptoticd se generalizeazA in mod natural si pentru functii cu mai multe variable. Astfel, pentru 0 funeiiearbitrara f Nx N= [0, 00) definim O(f) = {t:N x N— (0,00) | 3e > 0, 3no, mo € N, astfel incat V m2>mo,¥ n>no avem t(m,n) < e+ f(m.n)}. Similar se objin gi celelalte generalizi 9.3 Tehnici de analiza algoritmilor [Nu existi o metodé standard pentru analiza eficienjei unui algoritm. Este mai curind 0 chestiune de rajionament, intuijie $i experien{a. Vom aria pe bari de exemple cum se poate efectua o astfel de analiza. 93.1 Sortarea prin selectie Considerim algoritmul de sortare prin selectia minimului, reprodus mai jo: 9.3 TBHNICI DE ANALIZA ALGORFTMILOR pentrui =1,n-1 ‘Yhe caleuleaza poritia minimului lui a(i),a(é +1),-..,a(n) PozMin € i /initaliziom minimul cu indicele primului element pentruj=itin ‘daca a(j) < a(PozMin) atunci PozMin = j sfarsit daca first pentru Maupaj Mse aseazii minimul pe pozitia i aur = a(i) a(i) € a(PozMin) a(PozMin) + auz sfarsit pentru dupa i Timpul necesar pens o singur8 execuie a eicului pentru dupa variabils j poate fi mirgint superior de o constants «In total, pent un Bixat, findnd font de fatal mult b-+ a(n ~ 4) unit, unde beste o constant reprezentind timp pent iniializarea buelei,O singur execoie a bucleienterioare ae loc in cel mult e-+b-+ a(n ~ i) unig de imp, unde eesteo alti constant. Tinnd cont de faprl cd bucla dup j se realizeazt de n- ori timpul total de execusie al ‘lgoritmutu este cel mut: d+ DiS (c+b+a(n—i)) se realizeazi n-i iterafi, acest ciclu necesita un timp de cel Uniti de timp, d find din now o constanti, Simplificdm aceasté expresie gi objinem $n? + (b+.e— $)n-+ (d— ¢~}), de unde deducem ci algoritmul necesiti tn timp in O(n?). O analiza similar asupea limite’ inferioare aac cd timpul este de fapt in @(n2). Nu este necesar si considerim cazul cel mai nefavorabil sau cazul mediu deoarece timpul de executi al sorte prin select este independent de ordonarea prealabili a elementelor de sorta. fn acest prim exemplu am analizat toate detaliile. De obicet inst, detalii cum af fi timpul necesar inijializarii cicluslor nu se vor considera explicit, deoarece ele nu afecteazA ordinul de complexitate al algoritmului. Pentru cele ‘mai multe situafi, este sufcient si alegem o anumit® instrucjiune din algoritm ca baromeiru sisi numirim de cite of se executéaceastinstrejiune. in cazul nostri, putem alege ca barometru testul ali] < ofPozMin] din buca interioari, Este ugor de observat ck acest test se executi de 25-2 2 93, TEHNICI DE ANALIZA ALGORITMILOR 93.2 Sortarea prin insertie ‘Timpal pentru algorismul de sortare prin insertie este dependent de ordo- nnarea prealabili a elementelor de sortat, Algoritmul este implementat in cadrul primului volum, la capitolul Mogtenire, sectiunea Extinderea clasei Shape. A~ naliza algoritmului se realizeaza pe baza implementisii prezentate in cadrul acelei sectiuni, Vom folosi comparayia tmp.lessThan(alj - 11) din cichl for ca barometr, ‘Si presupunem ci p este fixat si fie n = a.tength lungimea sirului, Cel ‘mai nefavorabil caz.apare atunci cind trap < alj — 1] pentra fiecare jintre p si 1, algoritmul ficdnd fn aceasté situa p comparayii. Acest Iueru se intém- pla (pentru fiecare valoare a lui p de la I la n ~ 1) atunci efnd tabloul a este inigial ordonat descresedtor. Numarul total de comparagii pentru eazul eel mai nefavorabil este: Dit i= € O(n") Vom estima acum timpul meds necesar pentru ncaz oarecere, Presuptnem cltclementeletaloului a sunt distinct si eX orice permutare alo are aceasi probabilitate de aparitie, Atunci, daci 1 < k < p, probabilitatea ca alp] si fie cel de-al k-lea cel mai mare clement dintre elementele a{1],a[2),...,alp] este 4, Pentra un p fixat, conditia alp] < alp — 1] este falsi cu probabilitatea 4, deci probabilitatea ca si se execute comparatia "tmp < alj — 1]" o singurit dati inainte de iesirea din bucla while este . Comparatia "tmp < alj ~ 1)" se executi de exact doud or tot eu probabilitatea £ ete, Probabilitatea ca si se execute comparaia de exact p— 1 ori este 2, deoareceaccasta se inp aft cind tmp < af0] cat si cindaf0] < tmp It (n> 0) . ot 5 hanoi(n = 1, 1,6 = 1 = 05 ‘ System. out. printin(i # "5" + J): 9 hanoi(a— 16— ij. 1s so ” Pentru rezolvarea problemei inijiale, facem apelul hanoi (64, 1, 2): m4 94, ANALIZA ALGORFTMILOR RECURSIVL Considerim instucjiunea print in ca barometr. Timpul necesar agri aula este exprimat prin urmtoarerecurengh 1 dict n=1 an) teeter doch n>1 Vom demonstra ci t(n) = 2" — 1, Rezulti ch t € ©(2") Aces algoritm este optim in sensul ef este imposibil si mutim discuri de peo tj pe alta cu mai putin de 2* ~1 opera Penta a muta 64 de discur vor fin consecinfinecesare un numir astronomic de 2 opera. Implementarea ‘riare limbaj de programae care admie exprimarea recursivi se poate face aproape in mod direct. 9.4 Analiza algoritmilor recursi ‘Am vzut in exemplul precedent eft de putemic’ si in acelasi timp eft de elegant este recursivitatea in elaborarea unui algoritm. Cel mai impor: tant cigtg al exprimiit recursive este faptl cde este natural gi compacta, fick st ascundl esenqaalgoritmului prin detalile de implementare. Pe de alti pare, apelurile recursive tebuie folosite eu discemnimént, deoarece solicits st ele resursele calculatoralu timp 3% memorie). Analiza unui algoritm recurs implied aproape incotdeauna rezolvarea unui sistem de recurene. Vom vedea in continuare cum pot frezolvate atfel de recurenfe.Incepem cu tehnica cea mai simpli. 9.4.1 Metoda iteratiei Cu pusindexperieng si inmiie putem rezolva de multe ort asfel de 1e- curene prin metodaiterajie: se execu primii passe inueste forma genera- 1 iar apoi se demonstreazi prin inducie matematica ct forma este coretd. Si considerim de exemplu recurenja probleme tumurilor din Hanoi. Se observ’ ciipentra a muta n discuri este necesar si mutim n — 1 discuri, poi si muti un discs in final din nou n ~ 1 discui i consecin,pentro un anumit n > 1 objinem suceesiv: t(n) 2-141) + D732 2e(n-1) +1 =2e(n-2) +241 = Rezulti ci t(n) = 2” ~ 1, Prin inducjie matematicy se demonstreazat acum cou usuringi cd aceasta forma general este corecti. 25 94 ANALIZA ALGORFTMILOR RECURSIVI 9.4.2 Induetia constructiva Induefia matematicd este folosité de obicei ca tehnick de demonstrare a unei asertiuni deja enunjate. Vom vedea in aceasti secjiune ed inducyia matematicd poate fi utilizaté cu succes si in descoperirea parfalt a enunjului asertunii. A- plicind aceasti tehnicd, putem simultan si demonstrim o aseryiune doar paral specificati si si descoperim specificaiile care lipsese gi datorta cirora aserti- tunea este corecti, Vom vedea ei aceasta tehnic’ a inducfiei constructive este utili pentru rezolvarea anumitor recurenfe care aparin contextul analizei algo- ritmilor. incepem cu un exemplu, Fie functia f : N+ N definita prin recurenja: 0 dacs n=1 Fn) -{ f(n—1) +n altel ‘Si presupunem pentru moment cf nu stim c& f(n) = Aven S(n) = Digi s Don =n? sideci f(n) € O(n?). Aceasta ne sugereazi si formulim ipoteza inductiei specificate partial IISP(n) conform citeia f este de forma f(n) = an® +n + €. Aceastéipotezi este parfald in sensul c& a, b si nu sunt inc8 cunoscute © consti in a demonstra prin inductie matematica aceasta ipotezA incompleti sia determina in acelagi timp valorile constantelor necunoscute a,b sic. Presupunem ca /ISP(n-1) este adevarata pentru un anumit n > 1. Atunci, S(v-1) = aln—1)?-40(n—1) +e = an?-+(1+)—2a)n-+(a—b+c). Daci dorim ‘si artim c& //SP(n) este adeviratd, trebuie sit artim c& f(n) = an? + bn +e. Prin identiicarea coeficienilor puterilor lin, objinem ecuagile 1 +b ~ 2a = sia—b+e = c,cu solutiaa 4, ¢ putind fi oarecare. Avem acum 0 ipotezd “mai completa” (abuzul de limbaj este inevitabi), pe eare © numim tot ISP(n), f(n) = 3 + 3 +c. Am ardtat c& dact I/SP(n-1) este adevaratt pentru un anumit n > 1, aunei este adevarat si 1SP(n). Ramane s8 artim eX este adevirata si ISP(0). Trebuie si aritim c& f(0) = a0? + 60 +c. Stim ck $(0) = 0, deci HSP(O) este adevatati pentru c = 0, In concluzie am demonstrat, ci f(n) = % + 3 pentru orice n. 9.43 Recurente liniare omogene Exist din feriite gi tehnici care pot fi folosite aproape automat pentru a re- zolva anumite clase de recurenje. Vom incepe prin a considera ecuaii recurente Tiniare omogene, adic ecuatii de forma: 26 94, ANALIZA ALGORFTMILOR RECURSIVL Agty + itn tet aKty unde x este o constant (deocamdati necunoscut). Dac inlocuim aceasti solufie in ecuagia (*), objinem gz” + aya"! 4... aga Solufiie acestei ecuapi sunt fe solugia trivial. fie solusile ecuatie ), care nu ne intereseazi, agat att! +. tay = ‘care se numeste ecuafia caracteristica a recurentei liniare si omogene (*) Presupundnd deocamdati ci cele kridacini r1,r2,-..,1p ale acestei ecuafi ‘caracteristce sunt distincte, se verificd ugor cd orice combinafie iniard te = Dh er? ste o solutie a recurenfei (*) unde constantele cy, ¢2,..-,¢k sunt determinate le. Se poate demonstra faptul c& (*) are solujii numai de aceasta forma. ‘Si exemplificim prin recurenja care defineste girul lui Fibonacci ty = tat + tran 22 iar to = 0,, = 1 . Putem si rescriem aceastf recurenf sub forma ty tra tha =0 ‘care are ecuafia caractersticd 0 uridine ria = 53, Sotuia general are forma tart terk De fp, adel este ac au et vorba de intuit, i de experent. 94 ANALIZA ALGORFTMILOR RECURSIVI Impundnd condigile inifiale, to = 0,f, = 1, obginem ate =0n=0 an ter =1n de unde determinm os Deci, ty = Jp(rf +18). Observim cd my = yr = "si objinem: ye -(-") care este cunoscuta relate a lui Moivre, descoperitala inceputul secolului XVII Na prezinti nici o diicultate si aritim acum e& timpul pentru ealeulul reeursiv al sirului lui Fibonacci este in @(¢"). ‘Cum procedim insi atunci cénd ridacinile ecuatici caracteristice nu sunt distincte? Se poate arita cl daca r este 0 ridicin’ de muliplicitate m a ecuati caracteristice, atunci tn = 1" ,tn in = Posty = ED sunt solufii pentru (*). Solujia generali pentru o astfel de recurenja este atunci ‘© combinatic liniara a acestor termeni si a termenilor proveniti de la celelalte idicini ale ecuafiei caracteristice. Din nou, sunt de determinat exact k con- stante din condifileiniiale. Vom da din nou un exemplu. Fie recurenja by = Stn ~ Blna2 + Atma cu fo = 0,th = 1, ta = 2. Eeuatia caracteristicl are tidicinile | (de multiplici- tate 1) $i 2 (de multiplicitate 2). Soluyia generald este: 4 ex" +02" + end" Din conditile initiale, objinem ey = ~2,¢2 = 2,3 9.4.4 Recurente li Considerim acum recurenje de urmatoarea forma mai general are neomogene Gotn + ditn—a + ++ Oetn—e = W*p{n) (**) 28 94, ANALIZA ALGORFTMILOR RECURSIVL unde b este o constant, iar p(n) este un polinom in n de grad d, Ideea general’ este ca prin manipuliri convenabile si reducem un astfel de caz Ia o forma omogeni, De exemplu, 0 astfel de recurenga poate fi: ty — 2p fn acest caz b = 3 si p(n) = 1 un polinom de grad 0. O simpli manipulare ne permite sf reducem acest exemplu la forma (+). inmulfind recurenja cu 3, objinem: Btn — Gta = 3"? fntocuind pe n cu n + 1 fn recurenja original, avem: thei — Qty = arth fn final, setdem aceste dou ecuat si obginem tag — Btn + Bty. Am objinut o recuren{a omogent pe care 0 putem rezolva ca in sectiunea precedents, Ecuajia earacteristicd este 2252 +6=0 adici (2 -— 2)(2 -3 Intuitiv, observ c@ factoral (2 ~ 2) corespunde parti stingi a recurenfei originale, in timp ce factonal (2 ~ 3) a aparut ca rezltat al manipulator efec- tuate pentru a scipa de partea dreapta Tati un al doilea exemplu: ty Mn in + 5)3" Maniputirile necesare sunt pujin mai complicate. Trebuie siz 1, famutkim recurena cu 9: 2, Inlocuim in recurengaipem cu n+ 3. Inlocuim in recurents pe m eu n +1 ss iamuljim apoi eu -6 Adunfind cele tei ecuatii objinute anterior aver: 94 ANALIZA ALGORIFMILOR RECURS! tng2 — tng + 2ty — 18,1 = 0 ‘Am ajuns din nou la 0 ecuafie omogen’. Eeuay cearacteristic corespunzi- 82? +212 — 18 adiex (2 — 2)(— 39°. inci o dati, observim ei factorul (x — 2) provine din partea stingi a re- ccurenjei originale, in timp ce factorul (z ~ 3)* este rezultatul manipula Generalizind acest procedeu, se poate arita c& pentru a rezolva (**) este suficient si udm urmatoarea ecuayie caracteristic (agz* + a,x! +... +a4)(2— 441 = 0 Odati ce sa objinut aceasti ecualie, se procedeazi ca in cazul omogen. ‘Vom rezolva acum recurenia corespunzitoare probleme’ turnurilor din Hanoi ty = 2p t1n>1 iar fo = 0. Rescriem recurenja astfel ty — tna = 1 care este de forma (+*) cu b= 1 sip(n) = 1, un polinom cu grad 0. Eeuatia caracteristici este atunci (x — 1)(x — 2), cu sotusile I si 2. Solutia generali a recurenfei ese: th =e +02" ‘Avem nevoie de dou’ conditiiiniiale. Stim c’ to = 0; pentru a gisi cea de-a doua conditie caleulam 4 tot 1, Din condigile initiate, objinem tn Observaie: daci ne intereseaza doar ordinul lui ta, nu este necesar si calk culim efectiv constantele in soluyia general. Dacd stim cl ty = e,1" +622", rezulti ci ty € O(2"). Din faptul cl muméral de mutaei a unor discuri nu poate fi negativ sau constant (deoarece avem in mod evident ty > n), deducem ci 2 > 0. Avem atunci ty € (2%) si deci ty € @(2"). Putem obtine chiar ceva ‘mai mult ‘Substituind solutia generala inapoi in recurenta originara, gsi 1=ty—2ty ey +022" — (cy +22") Indiferent de conditiainigal, cy este 1 30 94, ANALIZA ALGORITMILOR RECURSIVL 9.4.5 Schimbarea variabilei Uneori putem rezolva recurenje mai complicate prinino schimbare de vai- abits. fn exemplele care uemeazs, vom nota cu 7(n) termenul genera al re- arene’ si cu ty termenul noi recurenge objinute print-o schimbare de vari- abili. Presupunem pentru inceput cm este o puere a lui 2 Un prim exemplu este recurenja T(n) =4T() +n >1 {in care tnlocuim pe m eu 2*, notim ty = T(2*) = 7(n) si objinem th = Ate +2" Ecuatia caracteristicd a acestei recurenf liniare este (conform paragrafului (2-4)(2-2)=0 sideci ty = c14¥ + 622, Inlocuim pe k cu Ign T(n) =eyn? + ean Remulti ch T(n) € O(n? | nesteoputere alui 2), Un al doilea exemplu fl reprezinté ecuayia T(n) =47(3) +n2,n>1 Procedind la fel, ajungem la recurenja te = Ate +4 cu ecuafia caracteristic& (e- 4) =0 si solufia general ty = c14* + exkA¥, Atunci, T(n) = crn? +ean? Ign si objinem cx T(n) € O(n? logn | nesteoputerealui2). fn fine, si considerdm st exemplul a 94 ANALIZA ALGORFTMILOR RECURSIVI T(n) =37(3) +en,n >1 ¢ fiind o constants. Objinem succesiv T(2*) = 37 (2-1) + 2 th = Sta +2 cu ecuafia caracteristicd (e~3)(@-2)=0 te =a3' +e,2* Pin) = 43!" +n $i, deoarece als) = yao obyinem T(n) = ern! +e.n deci, T(n) € O(n'¥? | neste oputerealui 2) {In toate aceste exemple am folosit notafia asimptotica conditionata. Pentru 4 arita ci rezulatele objinute sunt adevirate pentru orice m, este sufcient si adiugim conditia ca T(n) si fie crescatoare pentru n > No Putem enunjaacum o proprietate care este ui caret pentru analiza algo- ‘milor eu recursivitati de forma celor din exemplele precedente. Proprietatea, acirei demonstrareo lism ca exerciiu este foarte wil Ia analiza algoritmilor Divide et Impera, Propozije. Fie T : N ~> RX o functie nedescrescitoare T(n) = a (3) +ent,n > no unde ng > 1, > 2 si k > 0 sunt intreg, a gic sunt numere reale pozitive, iar Beste o putere a lui b. Atunci aver: (nt) daca < be Tin) € 4 O(ntlogn) dach_a=b* (niles) daca >be 2 95. IMPLEMENTAREA ALGORITMILOR 9.5 Implementarea algoritmilor ‘Am considerat utili prezenja la sfirgtul capitolului a implementisilor Java pentru problemele prezentate pe parcursul acestui capitol. Este cazul algorit- milor de sortare prin seleefie, a celui de sortare prin insergie gia algoritmulut ‘urnurilordin Hanoi, Listing 9.2: Implementarea algoritmului de sortare prin selecjia minimului import java-io.es slmport to-Reader: tie So Sortare prin selectia minimului lic class SortareSelMin Jes Ordonarea prin selectia minimulul.+/ wblic static void ordonare (int {] a) ( for (int i = 0; § < actength — int) fi Int_pozMin for (int j= i +1; j 0) RR Camp < al) — ID: i » ot > aU = at ~ 01 a , > aly) = imp: so = 2B /es Programul principal.+/ public static void main(String [] ares) > > | Hettirea elementetor siratut hs System-out. printin("Tntroduceti elementele sirului" + s "" (peaceeasi linie, separate prin spatiu):"): > Unt (5 = Reader, readintArray Os % ordonare(s): 95. IMPLEMENTAREA ALGORITMILOR » Hafisare reculiate % System-out.print("Sirul ordonat este: *) for (int i= 0; 1 < sylength; 144) rn fs Systemout. print (sil +" oy System. out.printin Q) : oy “) Listing 9.4: Implementarea problemei tumnurilor din Hanoi Import java-io.+: Hmport io. Reader; 38 Turmurite din Hanoi Spublie class Hanoi a +) fae Implementarea algorismului “Turnurite din Havol”. +/ oS public statle void hanoi(int -n, iat iy ime j) ad 5 i (0) » ot he hanoi(n = 1, 1, 6 1 js 's System. our. printinGi +" + De Me hanoi(n = 1,6 = b= J, ie sy a 3 fee Programul principal. +/ public static void main(String (] args) af b System-outprint("Tntroduceti umarul de diseuri: *): Int 9 = Reader. readint Os apelut metodei hanoi » — hanoi(n, Ty 2): 4 ” Rezumat Capitolul de fay realizat o scurtiintroducere in domeniul vast al analizei algoritmilor. Ideea cea mai important care reiese de aici este c& algoritmii 35 95 IMPLEMENTAREA ALGORIFMILOR utilizayi afecteaza timpul de execusie al unui program mult mai drastic decdt antficile de programare. Algoritmii care au un timp de lucru exponengial nu sunt in general aplicabili pentru date de intrare de dimensiuni rezonabile, spre R° definim urmitoarea relate bi- nari: f < g dack O(f) C O(g). Demonstrati ct relajia"<" este o relayie de ondine partiald in muljimea functilor definite pe N si eu valori in R Indicayie: Trebuie ardiat cit relajia este reflexiva, tranzitiva si antisime- trica. Tineji cont de exercigil 3 5. Pentna oricare dou funciif,g : N > R'demonstrayi ci O(f + 9) = Ofmact( f,g)) unde sum gi maximul se iau punctual. 6. Fie f(n) = aman +... + an +o un polinom de grad m, cu dy > 0 Aratayi cd f € O(n), 1. Consideram afemasia O(n?) = O(n + (n? —n8)) = Ofmaa(n®,n? — n3)) = O(n). Unde este eroarea? 8, Consideram afirmayia 37? Olmaz(1 +2-+...+n)) =1424...4n€ O1424...4n) = O(n). Unde este eroarea? 9, Pentru oricare doua functii f, Q(f +9) = O(maz(f,9)) se iau punctual, N+ RY demonstrajict @(f)+0(4) nax(@(f),@(g)), unde suma si maximul 10, Analizajieficienja urmatoriloralgoritmi: (a) penimn i=1.n enim j=1,5 {opera elementari) () pentru i= 1,0 entra jel i+ {operate elementari) (©) pentru enim j=1,6 penta k=1,n {operatic elementari) (@ pentru enim jel pentma k=1.n Loperatie elementari) 11, Construiji un algoritm cu timpul in @(n log n). 38 95. IMPLEMENTAREA ALGORITMILOR 12. Fie un algoritm: pentru i=O.0 jet cittimp j<>0 ie idiv2 Gasiti ordinul exact al timpului de execute. 13, Rezolvaji urmatoarea recurenja: ty — Bty1— 4tn-2 = On > 2eu Ot 14, Care este timpul de executie pentru un algoritm recursiv cu recurenta: ty = Btn tn? Indicatie: Se ajunge la ecuatia caracteristica (a — 2)(w — 1)? = 0, iar solujia generald este ty = ¢,2" +21" +cgnl”. Rezultd ed ty € O(2"). Substituind solufia generala in recurenta, objinem ca, indiferent de con- ditia initiald, c2 = —2 si cg = —1. Atunci, toate solutile interesante ale recurenei trebuie st aibet cy > 0 si ele sunt toate in (2%), deci in 02"), 15. Siise calculeze secvenja de sum’ maxima, formati din termeni consecu- unui sir de numere, 39 10. Structuri de date Nu potiobtine intotdeauna ceea ce ores, dar, dact inerei, uneori vei objine ceca ce ai nevoie ‘Autor anonim oui programe care rezolvié aceeasi problemi pot si arate complet diferit. Unul poate fi extrem de lizibil, concis si ugor de modifieat pentru a se adapta la rezolvarea unor probleme aseminitoare, iar celilalt poate fl impenetrabil, ‘obscur, interminabil si dificil de modificat. Cele dou’ programe pot si difere atit de mult in ceea ce priveste durata de executie si necesarul de memorie incdt, pentru un anumit set de intrare, unul furnizeazi rispunsul dupii 2 secunde, iar celilalt dupa céteva secole! Experienja a demonstrat c& aceste diferenge sunt generate de structura pro- ‘gramului side structura datelor. Programele sunt scrise pentru a rezolva probleme reale, Structurarea pro- _gramului imparte problema si solujia ei in componente mai simple si mai ugor de injeles. Informatia care trebuie procesati este rejinuti in structuri de date (Cablouri, inregistrar, liste, sive, arbor, figere ete.), O structura de date gru- peazii datele, O structuri de date aleasi adecvat poate face operajile simple gi cficiente, iar una aleas neadecvat poate face operafiile alambicate gi ineficiente ‘Structurile de date congin informatie asupra clreia se opereaz’ in timpul ex- ‘ecufiei unui program, Despre programe obignuim si spunem c& procesea’ in- formajie,cind, de fapt, ele proceseazi structuri de date. Astfel, nu mai pare sur- prinzitor faptul c& structura datelor sia programelor sunt extrem de importante si cl ele trebuie corelate corespunzitor pentru a programa cu succes, Asimi- larea cunostinjelor legate de structuri de date si algoritmi,alaturi de stipanirea cconceptelor fundamentale ale programirii orientate pe obiecte, ii permit pro- ‘gramatorului si menjind o suprematie regal asupra programelor, astfel incdt 40 Figura 10.1: Inchiderea datelor intro cutie neaged. Datel pot fi accesste doar prin invocarea unei opera permis. Cutie neagrd Rezultat permisé operatie acestea si riména lizibile, usor de intrefinut si eficiente, chiar si atunci cind ‘erese in dimensivne. tat programele edt si datele au o anumiti structurare gi att structura pro- ‘gramului eft gi a datelor trebuie si fie adeevath problemei de rezolvat. Vom urmici si prezentim structurile de date nu ca un subiect teoretic izolat, ci ca pe un instrument esengial al procesului de rezolvare a problemelor care conduce la ‘rearea de programe eficient. Structurile de date sunt importante, deoarece modul in care programatorul lege si reprezinte datele afecteaz’i in mod semnificativ claritatea, concizia, viteza de executie si necesarul de memorie al programului. in acest capitol, eit sin cele care urmeazi, vom prezenta cum si folosim diferte structuri de date Pentru a crea programe corecte gi eficiente. Vom vedea cl operafile care tre- buie realizate asupra datelor sunt cele care determing care este cea mai potriviti, structuri de date care trebuie folosit Dezvoltarea de programe este dificil, mai ales atunei cAnd este fcutd fri nici un fel de strategie, Progamarea orientata pe obiecte, prezentata in prima parte a lucrari, usureaza mult dezvoltarea programelor si conduce la programe bine structurate, Ea consti in impajitea atenti a unei probleme complexe in componente mai simple a cdror interfayi este apoi cu usurinja combinati pentru a rezolva problema initial. Abstractizarea datelor const in a trata o colecjie de date extrigind aspectele sale esengiale, ignorind pe eat se poate detalile. Abstractizarea datelor reduce datele la o colectie si la operajiile cate se pot realiza asupra acestei colecti Efectul este ca $i cum colecjia de date ar fi inchisi ints-o cutie neagr (black box) impenetrabils,singurul mod de a accesa datele flind invocarea uneia sau ‘mai multor operafii permise (Figura 10.1). 41 Modul in care datele sunt agezate in acea cutie neagr gi modu fa care ope- raile se executi devin detalii irelevante!. Astfel de detalii determina eficienta progeamului, dar nu ii afecteaza struetura logics “Abstractizareadatelortrebuie privé mai degrabacao facilitate care ugureaza efortal de programare, si nu ca 0 noua constringere in prvinfa stilului de pro- gramare. Pentru a injeloge mai bine aceste noyiuni, si vedem cum poate fi new Object [DEFAULT_CAPACITY }: 1 (ee Adauga elemental x in stiva.sf 3 pabite veld porn oject x) s ‘ If (topPosition zt 3 | increasesiacksize (0: a elements length — 1) b elements{+stopPosition | = x3 nd few Mareste dimensiunea (capacitatea) stivel ex 102, stive + DEFAULT_CAPACITY atunci cand stiva este pling. */ Private void increaseStackSize () ‘ Object {)_newStack DEFAULT_CAPACTTY }: jew Object {elements .ength + Ucopiem elementele in noua stiva for (Int | = 0: 1 < elements length: i++) i ) newStack[i] = elements [i]: Melements devine nowa stiva clements = newStack: 1 fee Extrage elemental din varful stiver. «of Public vold pop() throws, UnderflowException ( 16 Cisempty 0) i throw new UnderflowException ("Stiva, vida”) ’ topPosition—: 1 Jes Returneaza elementul din varful stivei (uttimal adaugat).+/ Public Object top() throws, UnderflowException ( If Cisempty 0) i throw new UnderflowException ("Stiva vida.” ) return elements [topPosition |: 1 (ee Returneaza elementul din varful stivet si it elimina apoi din stiva.«/ public Object topAndPop() throws UnderflowException ( if (isEmpty 0) i throw new UnderflowException ("Stiva. vida") ) return elements [topPosition 1 49 102. srive SS /es Verifiea daca stiva ¢ vida. 4/ return topPos: a & /es Elimina toate elementele din stiva. «/ 2 public vold makeEmpty() ot S| topPosition = =1 wo “ Listing 10.6: Exempla de utilizare a stivei. Programul va afiga: Conjinutul stivei este 43.210 cimport datastructures dimport exceptions -« p/ae Clase de tes! simpla pentru 0 stiva, care adeuga 5 numere ts dupa care le extrage in ordine inverse */ Spublic class TestStack “ + public static void main(String [} args) oe 4 Stack $= new StackAr(o: & Hintroducem etemente in stiva for (int i= 0; 1 <5; i44) of be Sepush(mew Integer Gi))s soy © Yscoatem elementele din stiva si te afisam System-out. print(*Continutul stivei este: "): sony » 1 nO fer Gd a t 2 System. out. print(s.topAndPop() + * *) x , catch (UnderflowException ue) 103. cou Figura 10.3: Modelul unei cozi: adugarea la coada se face prin enqueue (), accesul prin get Front (), stergerea prin dequeue () ‘enqueue ‘dequeue, getFront Queue 10.3 Cozi © alt structra simp de date este coada, n multe situa este important si avem acces gisau si stergem ultimal element inserat. Dar, intr-un numa la fel de mare de stvati, acest lucra nu numa cd nu mai este important, este chiar nedorit, De exempt intro rea de calculatonre care au acces lao singurd im- primani este normal ca daci in coada de aseptare se afd mai multe documente prea fitipart,priortatea si fie acordaté documentali cel mai vechi. Acest Ivers mu numai ea este core, dar este gi necesarpentra a garanta c& documen- tul nu astcapt la infnit. Astfel, pe sstemele mar ese normal se floscasca cori de tipi Operaile fundamental suporate de cori sunt «© enqueue -inserarea unui clement la capitul cozii; + dequeue - stergetea primului element din coada, © getFront - .ccesul la primul element din coads, Figura 10.3 ilustreazi operajile pe 0 coadi. Traditional, metodele de- queue () si getFront () sunt combinate intr-una singura. Prima metoda retumeazi primul element, dupi care il scoate din coadi, in timp ce cea de-a ddous returneaza primul element Pri 2-1 scoate din coads. Implementarea structurii de coadi este aseminatoare pind la un punct cu cea a stivei. Coada pastreaza elementele intrun gir de obiecte eu o capacitate initial, iar dacd prin adiugiri repetate aceasti capacitate este atinsl, atunci ea vva fi mariti automat. Spre deosebire de stiva, coada are doi indici care indies poziiile de inceput si de sfarsit ale cozi Listing 10.7 ilusireazX interfaa pentru o coadi, in timp ce Listing 10.8 pre- inti o implementa a interfejei anterioare, bazati pe giruri. Spre deosebire de sl 103. cou stivi, in care adiugarea si extragerea unui element au loc Ia acelasi capt, in azul cori adiugarea are loc la final, dar stergerea se face de la inceput. Astfe, pentru a putea utiliza sirul element s la intreaga lui capacitate,elementele lui ‘sunt privite “circular”, ca si cind ultimul element ar fi legat de primul. Listing 10.7: Interfaya pentru coud’ «package datastructures Simport exceptions .+; i/es Interfata peniru 0 coada. Expune metode pentru adeugarea Ss unui element, stergerea primului element, consulrarea G2 primulut element» Spublic Interface Queve a + puble vold enqueue (Object x): public Object getFront () throws UnderflowException : 5 publte Object dequeve () 5 public boi 5 public void makeEmpty 0: ") rows UnderflowException : an isEmpty 0) Listing 10.8: Implementarea unei structuri de jackage datastructures: Jimport exceptions .+: UD inplamentarea nel cott folosind um tablon. +/ ‘pubtte clase QueveAt Implements Quste | /** Tablow care retine elementele din coadas/ 1 private objec) clement + ee tnatcete: primal element / 2 pelvate tat roars Me tndicete wirimutai element s/ private tot backs i Pelvate tat cursencdize Retort de\slemente elocst initial peniru coadas/ Si pelvace Vinal static tne DEFAULT-CAPACHY 10, Ni feeConstructor care aloca memorie pentru clementele coztt Se si seteaza valorile atributelors/ % publte. Queuear() af clements = new Object [DEFAULT.CAPACITY }; 103. cou bs _ makeEmpty (): a Mo fen Intoarce true daca este vida.s/ public. boolean. isEmpty () af return currentSize == 0: = bs fee Adauga elementul x in coada, +f public: veld enqueue (Object x) a Af CcurrentSize == elements length) » ” increaseQueueSize () wy back = increment (back ); & elements [back] = x! fe currentSize +4 oo & fee Blimina toate clementele din conde. +/ Public veld makeEmpty( ( & currentSize S front = 0; Ss back fea Estrage primal element din cadral cozit NM s@ihrows UnderflowExeeption daca coada este goale+/ SS publle Object dequeue () throws UnderflowException wf 5 IF GsEmptyQ) no throw new UnderflowException ("Coada vida “4 & currentSize—-3 © Object returnValue = elements {front }s Me Tront = increment (front) “return retuenValue : en GS fee Intoarce primul element din cadrul cozti % Sethrows UnderflowEreeption daca coada este goale./ N public Object getFront() throws UnderflowException sf 3 103. cou > Af (isEmpty) no throw new UnderflowException ("Coada vida"); soy % return elements [front]; I t's Incrementeaza circular indicele din conda. / SX private int increment (int x) ot Sf (44x == elements length) So ns x=0 on an . Lo fax Incrementeaza dimensiunea cozii cu DEFAULT-CAPACTTY atunci & private vold increaseQueveSize() mi % "Object {] newQueve = new Object elements length + > DEFAULT.CAPACITY |; ws for Cint i = 0; 4 < elements length: 144) mf i -newQueve[i} = elements [4]: im front = increment (front }: mo} wm elements = newQueve: front > back = eurrentsize — 1 od Exercifiul 3 propune o a doua modalitate de a implementa aceasta interfati, si anume cu ajutorul listelor, care vor fi prezentate mai tirziu in cadrul acestui capitol. Listing 10.9 prezinti modul de utilizare a covii. Deoarece operatile pe ‘6 coadi sunt restricjionate int-un mod asemiinitor eu operafile pe o stivi, este de asteptat ca gi aceste operafii si fie implementate inte-un timp constant, Inte adevir, oate operajile pe o coada pot fi implementate in timp constant, O(). 34 Listing 10.9: Exempla de uilizare a cozii. Programul va afiga: Conjinutul coz este: 01234 import datastractures +; Hmport exceptions -+ d/ae Clasa simpla de test pentru 0 coada. Se ada t+ dupa care elementele sunt extrase pe rand */ Spublic class TestQueve 5 etemente. at +) public static void main(String (] args) oe +" Queue q = new QueveAr(: ' /Fadaugem elemenre in coada fo for Gime i= 0; 1 <5; 144) » ot Ne qvenquewe(new Integer(i))s sy 5 Yscoatem si afisam elementele din coada Ss System-out.print('Continatul cozit estes ")s so ouy » ster Gs) Q fi _ System. out. print (q. dequeue () + "Od » 4 catch (UndertlowBxception we) on a4 10.4 Liste inlantuite ino Hist tnlinguté elementele sunt refinute discontinuu, spre deosebire de siruri in care elementele sunt refinute in locaji continue. Acest Iuery este realizat prin stocarea fiectrui obit int-un nod care confine obiectl so refe- ‘inj cdtre urmatoral element io ist, ca in Figura 10.4. in acest model se rej referinge atit etre primul (fst) ft si cXtre utimul (ast element din list, Un nod al une! lst este implementat in Listing 10.10, Listing 10.10: Un nod al unei liste 35 tog. Liste INLANTURTE «package datastructures: 30+ Un mod al Listel intantuite. Clase este vizibita 4s doar in pacher (package-friendly ), deoarece este S$ pentru uzut intern al liste! aa Selass ListNode “ + fas Valoarea continuta de nod.»/ Object clement: fee Legatura catre nodul urmator.«/ bs ListNode next: 4 publte ListNode(Object element) clement = clement: ListNode(Object element, ListNode next) element = element In orice moment, putem adauga i list un now element x prin urmatoarcle operat: last next = new ListNode(x): //ereasa an nod cn continetal x ast o'tastenent; //nodul creat anterior cote aléimal in tiara fn cazal unei liste infinite un element oarecare nv mai poste fi gait eu un singuracces. Aceasia este oarecum similar eu diferena inte accesareaunet melodii pe CD (un singur acces) si accesarea unei melodii pe easetd (acces Seevental). Desi din acest motivlistle pot sh park mai putin atractive decdt simul, exist toi edteva avantaje importante. fn primal ind, inserarea unui Figura 10.4: O listi simplu inkinuit first last a ao as as 56 tog, Liste IMpANTUTE clement in mijlocl listei nu implick deplasarea tutor elementelor de dup punctul de inserare. Deplasarea datelor este foarte costisitoare (din punct de ‘vedere al timpalui, iar stele tnlinuite permit iserarea cu un mums constant de instuciun de atibuire Merithobservat ci dack permitem accesul doar la frst, atunciobjinem o stv, ia da permitem insriti doar la last i aceesiri doar la first, objinem 0 coadi, Exercijle 1 gi 3 de la fnaul acest capitol propun exact acest hens restritionarea operator pe o list penta a objineo stivi respect o coadi in general, atuneicind folosimo list, avem nevoie de mai multe opera. cum arf gisiea sau stergerea nui element onrecare din lis. Trebue sk per- miter sinseraea unui nou element in orice punct.Accasia este deja mul¢ mai tmult deci ne permite o stivi sano coadi. Pentns a acesa un clement in ist, tebuie si obsinem oreferingicte nodal care i corespunde. Evident cb ofeireauneireferinge edtre un element inca principiulascunderi informe. Trebue sine asigurim ci orice acces la stk Prin intermedi uneireeringe nu pericliteazi stuctura lise. Pentra a realiza acest ues, lista este defini in dou pi: o cas lists o cas iterator. Clas listi va refine elementele propriu-zse ale lise in timp ceiteratonal va ofr o modalitate de a parcurge si modifica etementelelistei fii a periclitastructura ci. Listing 10.12 fornizeara intrfaja de bard pene o list inlinuits,oferind si metodele care descr doar starea liste Listing 10.14 definesteo casi iterator care este folosté pens toate ope- rajle de accesare a iste. Pentru a vedea cum functioneazi\ aceasti clas, i examin seevenga de cod clasick pentru afigareatturorclementelor din cadral tneistructriliniare, Daca lista arf stocat int sir, secvenja de cod ar arta astiet: ‘H/parcurge sirul a, afisand flecare element sfor (Int index = 0; index < a.length; ++ index) Hl 1 System out. printin(alingex I): " {in Java elementar, codul pentru a itera o list este: \Uparcurge lista theList de tip List, afisand fiecare element Bor (ListNode p= theList. first; p != mull: p = p.next) a 4 System.out. printin(p. data); " Pe de altk parte, trebuie avut in vedere faptul c¥ anumite operagii in cadrul Tistet pot egua (de exemplu stergerea unui element inexistent), motiv pentru care este utilizatd urmatoarea clasa TtenNotFoundzxcept ion din Listing 7 tog. Liste INLANTURTE 10.11 Listing 10.11: Clasa de exceptii TeemtNot Foundexception «package exce s/ee Clase de exceptii care semmaleaca tentative de a cauta un te clement Inexistent tw cadrul ancl structurl de date #/ Spublie class ItemNotFoundException extends Exception “ +) public ItemNotFoundException () oe “4 public ItemNotFoundException String msg) ot he super (mse): wo “) super: Listing 10.12: Interfata pentru o lista abstract \ package datastructures: V/ae Interfata pentru un tip abstract de lista inlantuita. «/ ‘public Interface List fee Testeaza daca lista e vida. «/ boolean isEmpty Qs t/a Sterge toate elementele din lista, «/ old: makeEmpty 0: " Listing 10.13: Implementarea unei liste inkinjuite «package datastructures: 4 Lista simplu intantuita 5 + Accesarea elementelor se face cu lterarorul LinkedListltr 7 lic class LinkedList implements List + ListNode header: 4, LISTE INLANTUTE publle LinkedList() of Me header = mew ListNode (null); wd public bostean isEmpty () ad SS) return header.next == mull » 2 public: void. makeEmpty() af Bh header.next = nul = s) 1g 10.14: Interfags pentru u «Package datastructures: Nimport exceptions +5 ts Interfate iterator pextre parcurgeres elementelor nei Ft Uste inlantuite abstracte (simplu tnlantuita, dublu ft Intanruita, cireulara, ete.) public interface Listitr Jes Insereaza un element la positia curenta. «/ 5 Vold insert (Object x) throws. ItemNotFoundException : Slee “© Seteaza pozitia curenta pe elementul x daca nil gaseste tn lista boolean find (Object x): HN fe Sterge elementul x din Lista. af Yold remove( Object x) throws ItemNotFoundException M fxs Verifiea daca lista @ fost parcursa in toralitare. +/ = boolean islnList(); 2 /es Obtine elementul aflat pe pozitia eurenta. +f mM Object retrieve Qs B fee Seteaze positia imeintea primului element. «/ x old zeroth () 39 tog. Liste INLANTURTE n /es Seteaza positia curenta pe primul element. +/ be vold firsts fen Avanseaza in liste ta urmatorul clement. */ void advanced) Pornind de ta interfaa unei liste abstracte, codul pentru implementarea unei liste inkinquite este dat in Listing 10.13, iar implementareaiteratonului unei liste inkinuite este data in Listing 10.15, ‘Mecanismul de iterare pe care I-ar folosi limbajul Java ar fi similar eu us mitoarea secvenyi: \Uparcurge List, folosind abstractizarea si an iterator pListler ite = new LinkedListler(theList): for (itr. firsts ite istaList (Qs ite-advanee()) st 4 system. out. printin (itr retrieve ()s ” Inigiatizarea dinainteaciclului fr creeazdun iteratoral lise. Testl de er- iminarea ciclului flosegte metoda is TnLi.st () definté pentma clasa Linked- List Itz, Metoda advance () tece laurmatoru nd din caduliste. Putem access elementul curent prin apelul metodei retrieve () definitdin Linked- List Zee. Prineipiul general este cd accesl find realizat prin intermediulcla- sei List It, securitatea datelor este garantati, Putem avea mai mul iteratort care sf raversezesimultano singur list Pentru a functiona corect, clasa List Itz trebuie si mengind dous obiecte. fn primul rind, are nevoie de o referinjécatre nodul eurent. in al doilea rind ane nevoie deo referng8eitre obiectul de tip List pe care tl indick (aceastt refering este inijializat o singuri dat in cadrul constrctoruli). ing 10.15: Implementarea iteratorulu liste fokinquite «package datastructures Simport exceptions .¢; te Merator pentru lista inlantuite ter ‘public class LinkedListitr Implements Listrtr i fee Referinta catre lista care va fi iterate of Nl protected LinkedList theList bs TeeReferinta catre nodul eurent.4/ 5 protected ListNode current: 4, LISTE INLANTUTE JesConstruleste un iterator pe lista Uist e/ public LinkedListItr(LinkedList list) ( theList = list current = list isEmpty () 2 list header = list header next: 1 (es Construieste cu parametru de tip List. Daca list ‘+m refera o instanta LinkedList, se arunca 0 exceptie fide tipul ClassCastException +? Public LinkedListlie(List list) throws ClassCastException ( this ((LinkedList) list): 1 Jus Reseteaza iteratorul care va indica pozitia dinaintes ‘ primului element din Listas! public void zeroth () ‘ 1 ent = theList header Jes Adauga obiectul x la pozitia curenta in lista + @throws lemNotFoundException daca lista este vida +f Public yold insect (Object x) throws ItemNotFoundException ‘ ir (current t throw new ItemNotFoundException ("Eroare la inserare* ) > ListNode newNode = new ListNode(x, current .next) ent next = newNode 1 fos Intoarce true dace obiectal = se afla in liste +f public boolean find (Object x) ListNode itr = theList header next: white Cite t ) null && {itr clement equals (x)) ie Cite t return false: ) 6 tog, Liste INLANTURTE oe 1 Jes Sterge obiectul x din lista = Gihrows NemNotFoundEsception daca x me se afla in listas/ public vold remove( Object x) throws. ItemNotFoundException i ListNode itr = theList.header while (itr.next 1 c ull && tite next element equals (x)) i Gitrnext = ( throw new ItemNotFoundException (*Stergere esu: null) itromext = itrenextonexts //trecem peste modul sters current = theList header: ’ fos Imoarce clementul de pe potitia eurenta */ Public Object retrieve) i return (isinList () ? cvrrent.element > mull); ’ Jes Imoarce true daca ne aflam in interiorul Listel +/ public boolean. isinList() i return (current != mull) && (current ’ theList header): fxs Elementul curent va fl primal element din lista +f Public vold first () i current = theList.header.next 1 Jes Avanseaza iteratorul pe urmetorul element «/ public void advance () c In (current i ; : ) null) wel Tati i exemplul de utilizare a listei Listing 10.16; Exemplu de utilizare a listei, Programul va afiga: Conjinutul listei: 43.210 Import datastractures = Simport exceptions +: \/az Clasa simpla pentra testarca unei liste, care adauga $ numere ts dupa care afiseaza continutul lister.+/ Spublic class ‘TestList a 5) public statie vold main(String (} ergs) oe + List theList = new LinkedList (Qs ss Listtte itr = mew LinkedListlte(heList ys dae insereaza elemente pe prime positie for(int = 0; be 8: 4H) wot " y wo ® ite insert (new Intezer(i)): if ) % catch (ItemNotFoundException e) =f 5 1 > ite zeroth (05 //se trece ta inceputal listed uy % System-out.print("Continutul listei: *) for Cite first (Qs itr istnbist Qs ite advanceQ) in m System out. print (ite retrieve () + * ")s ny my ” Desi discujias-a axat pe liste simplu inlinuite,interfejele din Listing 10.12 si Listing 10.14 por fi folosite pentru oricare tip de lista, indiferent de imple- ‘mentatea pe care o are la baz8. Interfaja nu precizeaz’ faptul cd este nevoie de liste simplu inkanguite. cy 10S. ARBOR! Figura 10.5: Un arbore generic JN Ue 10.5 Arbori 10.5.1 Notiuni generale ‘Vom trece acum si studiem cele mai importante structur neliniare care apar {in algoritmil pentru caleulatoare: arbori. In general vorbind, structura arbores- ‘cent implicdo relgie de ramificare intre nodusi, foarte asemanstoare cele in- tilnite la crengile unui arbore din natura ‘Una dinte definite cele mai rispanite ale arborilor (nu neaparat bina) este urmatoarea (dupa D.E. Knuth): Definite: Un arbore (Figura 10.5) este o mulime fniti T de unul sau mai multe nodur, care ae proprictile: 4) exist un nod special, numit ridicina arboreluis ji) toate celelalte nodusi din T' sunt ropartizate in mulfimi T),T3y.--»T>u disjunct, flecare muljime la indul sau find un arbore. Arbor Ty,T3,---,Tm se numese subarbori rdacini Se observ ci definitia de mai sus este recursiva (recursvitatea este prezen- tata in capitol 12): am definitun arbore pe baza unorarbori Totus, privind ea atenjiedefinifia ne dim seama c8 nu se pune problema circularitii, deoarece un arbore cu un singur nod este aledtuit doar din riding, ae arborii ca n > 1 noduri sunt defini pe bazaarborilor cu mai pugin de n nodusi. Exist gi defini, nerecursive ale arborilor, dar defniia recursivi este mai adeevati, deoarece vom vedea ci recursivitatea pare si fie o trisiturl inerenté operatilor pe steuc- tur arborescente, Caracterul recursiv al arborlor este de altfl prezent si in natur8, deoarece muguti arborilor tines crese gi se dezvolté in subarbori, care Ja rindul lor fac mugusi si aga mai departe. [Nodul ridcini al fieciruisubarbore se mumeste il (sau copil)ridacinii, iar rcina este taal (sau parintele) fiecdrui nod ridacina din subarbor. "De expla cola graf, un arbre este defini caun graf cones ecu 64 105. ARBOR aK RB RI dg pase rm Din definitia rcursiva reiese cd un arbore este o colecfie de m nod, dintre care untl este ridcina,sin—1 muichi. Fatolc& exist n— 1 muchii se deduce din observatia simple flecare muchicleagt un nod de parintele stu i fecare nod, in afar de ridcin, are exact un print. fn arborcle din Figura 10.6, ridicina este 1. Nodul 5 il areca prime pe 1 si are fit 12,13 si 14. Nodurile cae nu au fi se numese frunze. Frunzele in arborele de mai sus sunt 8, 3, 12, 13, .. 21. Nodurile eu aceasi parinte $e numese fra, In mod asemanator se definexc relaile nepot, bane ec. Un drumde la unnod n; Iaun nod este osecvengde nodurim,725-+-sMe astfel inet m este tat hi nya pentru = 1, &— 1. Langimea unui drum este data de numarul de muchii ale drumului, adic’ k — 1, Pentru oricare nod nj, nivelul(adneimea) nodolui este hungimes unicului drum de la ridcina la Astfel,nivelal sie 0, In atborele din Figura 10.6, nivelul nodulai 2 ste I, ir al nodulai 15 este 3. Adincimea unui arbore este defnta ca find maximal adincimilornodurior. fn exemplul nostro, adéneimes arborelui este cgalieu adincimea nodului 15, care este 3 10.5.2 Arbor Defin fi Figura 10.7 arati chun arbore binar consti intro ridicin gi doi subarbort T, si Tg, oricare din ei putind si fie vid (si lipseased) (© proprietate deosebit de importants a arborilor bina este c& adéncimea medie a unui arbore binar cu n nodusi este considerabil mai mic deeat n. Se poate arita ci adincimea medie a unui arbore binar este proporfionala ca V7, jar adancimea medie a unui caz particular de arbore binar, arborele binar de 6s ‘Un arbore binar este un arbore in care orice nod are cel mult doi 10S. ARBOR! Figura 10.7: Arbore binar generic =) LX LS Figura 10.8: Exemple de arbori binari (a) arbore binar degenerat (b) arbore Dinar nedegenerat wm ® J ° $ fo ' g godbo 2 } é\ : é a lutare (sotunea 10.5.3), ese proportional cu login . Din picae, in cazurile degenerate, adancimea unui arbore poate fi chiar n~ 1, dupa cum se vede gin Figura 10.8¢@), fnahimea (adancimea) unui arbore bina este foarte important, deoarece molt operat definite asupra arborilor (stergere de nod, inseare de nod et.) sunt proportionate cu inaimea arborehi. Din acest moti, s-a recurs la difeite metode pentru a mentine adncimea unui arbore proportional’ cu log n in orice situate (arbori AVL, arbori bicolor et). Parcurgerea arborilor binari Dupti cum reiese si din Figura 10,7, putem defini un arbore binar ca flind 6 muljime finiti de noduri care este fie vida, fie este formatd dints-0 ridacind si doi arbori binari, Aceasti definijie sugereaza o metoda natural de reprezentare ‘ arborilor binari: fiecare nod va fi descris de tei componente: element - informajia uta a nodului, Left - o referinsa cdtre fiul din stinga si right - 66 105. ARBOR Figura 10.9: Reprezentarea inlinjuiti a arborilor din Figura 10.8 root FZ root Ao a ile o]a]o 4a) (oy o refering citre ful din dreapta. Dact un nod nu are fiu in stinga atunci Left este nu11, analog, dacd nu are fu in dreapta, atunci right este nul. Putem astfel defini clasa BinaryNode, care refine un nod al unui arbore binar: ‘public class BinaryNode at > Object element 4 BinaeyNode left; 5 BinaryNode right + Weonstructori si alte metode Informatia utili din cadrul nodului este refinuti de atributul eLement, c este de tip Object, deci poate referio instantade orice tip. Figura 10.9 prezin- ‘i modul in cate se reprezint’ inknquit arbori binari din Figura 10.8, Variabila oot din Figura 10.9 este o refering care indica ridicina arborelui, Exist mai mulfialgoritmi pentru manevrarea structurilor arborescente, si 0 idee care apate de foarte multe ori este nojiunea de parcurgere, de “deplasare’ prin arbore. Parcurgerea unui arbore este de fapt o metoda de examinare sis- {ematicd a nodurilor arborelui in asa fel inet fiecare nod si fie vizitato singuri 0 10S. ARBOR! dati, Parcurgerea completi a unui arbore ne oferiio aranjare linear’ a nodusilor, si operarea multor algoritmi este simplificatd dac stim care este urmatorul nod Ia care ne vom deplasa int-o astfel de secvenf, pornind de la un nod dat. Exist rei moduri principale in care un arbore binar poate fi parcurs: nodurile se pot vizita in preordine, inordine si in postordine, Vom deserie aceste trei metode recursiv, ca si definitia arborelui Dac un arbore binar este vid (nu are nici un nod) parcurgerea lui nu pre- supune nici o operatie; i caz contrar parcurgerea comport trei etape, descrise ul urmator: Teparune aor wing | Se viet iaciea | Se parry barbed Pentru arborele din Figura 10.3 gisim c8 nodurile in preordine sunt: ABDHIECFG deoarece mai inti se viziteazi rdicina A, apoi subarborele sting (B D-H T ) si apoi subarborele drept (C F<). ‘Similar, parcurgerea in inordine are ca rezultat sirul HDIBEAFCG iar parcurgerea in postordine: HIDEBFGCA [Numele de preordine, inordine gi postordine deriva, bineinjeles de la pozi- Jia relativi a ridicinii faja de subarbori. © posibili metod de a parcurge un arbore in preordine este dati in Listing 10.17. Metoda primeste ca parametru 0 referini citreridicina subarborelui care este vizitat. Evident ci la primul apel, parametrl este chiar ridiicina arborelui (referinja root din Figura 10.9). Vom. vedea cum se integreazii parcurgerea unui arbore in cadrul unei clase complete {in paragraful 10.5.3. Listing 10.17: Metodi generic’ pentru parcurgere binar preordine a unui arbore ‘bite vold preord(BinaryNode &) > process ( tuelement ) preord( toteft ) 5 Preord( toright ) 105. ARBOR Celelalte doutt parcurgeri se realizeazii absolut analog, prin simpla reor ddonare a instructiunilor de parcurgere, 10.5.3. Arbori binari de ciutare Una dintre cele mai importante aplicai ale arborilor este uilizarea acestora probleme de cdutare. Proprietatea care face ca un arbore binar si devina un arbore binar de edutare este: pentru orieare nod X al arborelui toate nodurile din subarborele sting sunt mai mici decit X, si toate nodurile din subarborele rept sunt mai mari decdt X. Agadar, fai de arborii binari obignuii, arborit de ciutare mai adaugi o relayie de ordine intre elemente. Pentru a putea fi comparate, nodurile nu var mai confine obiecte de tip Ob ject. cain paragraful 10.5.2, ci instanfe ale clasei Comparable. Arborele binar de © structuri de date in care, pe lang eiutare rapidd, putem adiuga sau sterge eficient elemente. Figura 10,10 ilustreaza operafiile de baz’ permise asupra unui arbore binar de clutare, Figura 10.10: Modelul pentru arborele binar de eiutare, inser’ find.remove SS 7 Arbore binar de cautare De exemplu, arbori din Figura 10.8 nu sunt arbori binari de ciutare, deoa- rece, in ambele cazuti, in stinga nodului A se afl nodul B, care are valoare mai ‘mare decat A (dac’ considerim ordinea alfabeticd). ‘SA studiem cu atenjie arborii din Figura 10.11. La prima vedere, ambii par si fie arbori binari de ciutare; examindnd totusi mai minujios arborele din dreapta, constatim e% nodul 7, desi este mai mare decdt rdicina, 6, se afl in stinga ei, ceea ce contravine regulii arborilor de cdutare. Co) 10S. ARBOR! Figura 10.11: Doi arbori binari. Doar arborele din stinga este si arbore binar de cutare, Principalele operaii care se realizeazi asupra arborilor binari de ciutare sant: # Ciutarea unui nod fn arbore; © Gisirea minimului si maximuluis « Inserarea unui now nod; « Stergerea unui now nod; + Videreaarboreui(tergerea tuturor nodurilon. © posibisinterfgh care descrieaceste opera este prezentatiin Listing 10.19. Setul de oper permise este acum extns fat de stv si cond pentra 8 permite gisiea unui element arbitrar, alituri de inserare gi stergere. Metoda Find () intone o refernfS cite un obiect care este egal (in sensul metodei compareTo() din intrfafa Comparable) cu clementul efutat. Dact ni xis nici un element egal eu el eluta, find) anuned 0 exceptie Teen NotFound=xcept ion, prezenaté in seciunea anterioars. Accasta este 0 decizie de proietare. O ali posibiitate arf fost si intoareem a1 in cazul fn care clementulciutat nu este gisit. Diferenja inte cele doud abordiri con- Sti in faptul ck metoda noasti il oblig pe programator si trateze explicit situajia fn care efutarea nu are succes. fn ceaalts situaie, dacd am fi fn- tors nul}, si nu sa fi flcut verfcdile necesare, programul ar fi generat un 70 105. ARBOR Listing 10.18: Clasa de excepfie DuplicateTtemException \ package exceptions: i/ae Clara de exceptii core remnaleaza adaugarea unui clement deja ipublic class DuplicateltemException extends Exception a } public DuplicatettemException () et 5 supers “4 © publte DuplicateltemException (String msg) of ue super(mse): od “ Nul1PointerException la prima tentativa dea folosi referinja, Din punct de vedere al eficienje, versiunea cu exceptii ar putea fi ceva mai lenta, dar este pujin probabil ca rezultatul si fie observabil, cu except situajiet in care codul ar fi foarte des executat in cadrul unor situaii in care viteza este critic’. fn mod similar, inserarea unui element care dea est in arbore este sem- nalataprint-o exceptie Dupi icatertenExcept ion (veri Listing 10.18) Exist i alte posiile altemative, Una dinte ele const in permite noi valor si suprasrievaloarea soca ‘Vom da ca exemplu un arbore de cutare care rejine stringuri. Acest lueru este posibil deoarece String implementeaza imterfaja Comparable, Im- plementarea arborelui binar in conformitate cu interfaja SearchTree este prezentati in Listing 10.21. Pentru a implementa nodurile arborelui binar se utilizeazi clasa BinaryNode, prezentati in Listing 10,20, Implementarea arborelui binar de efutare este mult mai complexi decit pen- mu stiva sau coadi gi foloseste recursivitatea (care va fi prezentati in eapitolul 12), Nu vi ingrijoragi daci nu injelege{i acum toate detalile de implementare; putefi trece mai departe (Grd nici o problema si reveni mai tirziu, dup’ ce ai parcuss si injeles capitolul 12. ‘Toate elementele din arborele binar ne sunt accesible prin intermediul ri- icinii sale, care este refinuti in atributul root. Si descriem acum pe scurt modul de functionare al metodelor din clasa BinazySearchTree, n 10S. ARBOR! Listing 10.19: Interfaja pentru un arbore binar de ciutare «package datastructures: SImport exceptions .+ ts Interfata pentru arbori binari de cautare. Expune metode + pentru adaugarea $1 stergerea unui element oarecare si ts pentru adaugarea si stergerea efementului minim si maxin public interface SearchTree af yold insert (Comp: 5 Yold remove( Comparable x) throws We Yold removeMin() throws Item’ ‘Comparable’ find (Comparable x) throws ItemNotFoundBxception : ‘© Comparable findMin() throws [temNotFoundException : 5 Comparable findMax () throws ItemNotFoundException : boolean isEmpty Q: 8 yold: makeEmpty 0): Ciutarea unui nod in arbore: Asa cum le spune gi numele, arborii binari de ciutare au fost concepui pentru a se putea ciuta informatie rapid si usor. Si presupunem cit fn arborele de ciutare din Figura 10.11 (cel din stanga), dorim si gisim nodul care are cheia 4, Pentru aceasta comparim valoarea 4 cu ridicina, Deoarece 4<6, nodul ciutat se aflé in subarborele sting, care are Fidaicina 2, Compariim4 cu 2. Deoarece 4>2, nodul ciutat se afl in subarborele drept. Comparim pe 4 cu fiul din dreapta al lui 2, constatim ca valorile sunt ‘gale si ne oprim, Dacd in loc de cheia 4 am fi cAutat cheia 5, atunci am fi ajuns in subarborele drept al lui 4, care este vid, deci nodul 5 nu se giiseste in arbor. (Ciutarea unui nod se realizeazai cu metoda £ ind () implementatin liniile 75-95 din Listing 10,21. Aceasti metodi porneste cu clutarea de la riiicina ar- borelui si coboar’ fie edtrestinga fe cdtre dreapta (funejie de relajia dintre ele- ‘mentul etutat si ridcina subarborelui) pan clind elemental eStat este gsi s- si” din arbore, caz in care se arunci\/o TtemNotFoundException () Gisirea clementului minim si a celui maxim: Gisirea elementului minim (gisirea maximului se face analog) consti pur si simplu in a cobori in arbore pe ppartea sting (liniile 105-108) pani se ajunge la frunz’i, Elementul din frunzit este chiar minimul, n 105. ARBOR Listing 10.20: Clasa care modeleaza un nod al unui arbore binar «package datastructures: te Represinta un nod in arbore. Este pentru uz intern telus BinaryNode © Comparable elemen + BinaryNode left vw BinaryNode rig! 5 BinaryNode(Comparable ) wee mo lett eight a = BinaryNode(Comparable ©, BinaryNode It, BinaryNode rt) no 2D element left = 1k fight = ty Adijugarea unui nod in arbore: Adiugarea unui nod in arbore se realizeazai folosind metoa insert (Comparable) din linile 20-24, care la rindul et delegi problema citre insert (Comparable, BinaryNode) de la liniile 129-150. Probabil c& vi intrebati de ce a fost nevoie si scindim operatia de adaugare in dou metode? Metoda propriu-2ist de stergere are si un parameteu de tip BinaryNode, care Ia inceput este chiar root, ridicina arborelui. Uti- lizatorul obignuit nu are acces la acest atribut, de aceea el poate apela doar metoda insert (Comparable), care fiind o metoda din cadrul clasei, va putea apela la linia 23 insert (x, root). Aceasti tehnici este folositi pen- tru toate metodele existente in clasa BinarySearchTree Metoda de adiugare a unui nod in arbore este conceptual destul de simpli Pentru a insera x in arborele cu ridacina t, ne “afundim” in interiorul arborelui exact ca gi in cazul metodei find (). Daci valoarea x este gisiti in arbore, atunci aruncim DuplicateTtemExcept ion. in caz contrar inserdim un nod cu cheia x, in ultimul punet din calea care a fost parcursi, Figura 10.12 B 10S. ARBOR! Figura 10.12: Arborele binar de ciutare inainte gi dupa inserarea noduluiS. ne arati ce se petrece. Pentru a insera valoarea 5, traversiim arborele ca si cind am realiza procesul de ciutare. Cand ajungem la nodul cu cheia 4, trebuie si ‘mergem cdtre dreapta, dar nu existi subarbore drept, deci 5 nu este in arbore gi acesta este locul in cate trebuie inserat Ca orice metoda recursiva, insert () incepe la linia 132 eu conditia de terminare: wee ccare este adeviirati in momentul in care subarborele curent este vid. fn acest ‘caz se creeazi pur si simplu un now nod in care se plaseaz’ obiectul x gi se ac- tualizeza ridacina subarborelui cu nodul curent, in cazul in care subarborele in ‘cate se insereazs x nu este Vid, comparim x cu valoarea din ridiicina arborelui: x compareTo( t-element ) Dacé valoarea din este mai mic, atunci x se va insera in subarborele sting: oleft = insert, tem) altel, dae este mai mare se va insera in subarborele drept: Lovight = insert(x, toright) ine daci valorile sunt eyaleinseamni cd nodulrespetivexista deja in arbore gi se anunci o Duplicatetten=xcept ion Metoda insezt () confine un aspect de finefe: cum se leagi noul nod inserat (5 in exemplol nost) detail sau (4)? fn metoda insert () nu pare Si existe 0 secvenfi de cod care si semnaleze ci ful din dreapta al hi 4 nu mai este na, ei este noul nod insert. Réspunsi se afi in modul in care se 4 105. ARBOR realizezii apelul recursiv al metodei insert () : subarborelui sting (sau drept) curent i se atribuie rezultatul inseririi nodului x curent. La un moment dat, metoda Va crea un nou nod, iar adresa acelui nod va fi intoarsi ede nodul parinte Stergerea clementului minim sia celui maxim: | Stergerea clementului minim gisirea lui, du subarborele drept in locul lui, Metoda removeMin () dela linile 152-170 realizeaza exact acest lucru., Observafi ci aici, pentru variajie,ciclul wh ie de la linile 105-108 ale metodei findMin () ‘fost inlocuit eu un apel recursiv. “Ridicarea” subarborelui drept in locul ele- ‘mentului sters se face simplu, prin atribuirea de la linia 166: const are se “ridi toeiant ‘Stergerea elementului maxim se realizeazi absolut analog. Stergerea unui nod din arbore: Operatia de stergere a unui nod este cea ‘mai delicati operatie pe arborele binar de ciutare, deoarece pe ling’ eliminarea, rnodului mai implied si operafii suplimentare pentru a pastra siructura de arbore binat. In cazul operatici de stergere, dupa ce am gisit nodul care trebuie sters trebuie si considerim mai multe posiiliii: ‘ Dacit nodul care trebuie sters este o frunzi, el poate fi sters imediat prin Inlocuirea leg’turii pirintelui stu cu nui 1; # Dac nodul care tebuie slers are doar un singur fiu (indiferent c& este sting sau drept), stergerea lui se face prin ajustarea legaturi parintelui siu pentru al “ocoli” (Figura 10.13); © Cazul complicat apare atunci cnd nodul care trebuie sters are doi fi Strategia generalA in acest caz. este de a inlocui cheia nodului care tre- buie sters cu cea mai mic& cheie din subarborele stu drept (care este uusor de gisit) dupa care nodul cu aceasta cheie se sterge folosind metoda removeltin () descrisa anterior (Figura 10.14). ‘Stergerea unui nod din arbore se realizeazi folosind metoda remove (Com parable) din liniile 28-32, care la rindul ei delegi problema citre remove- (Comparable, BinaryNode) de la linile 172-199. Ca orice metoda recur- sivd, remove () incepe la linia 175 cu conditia de terminare: wee > 15 10S. ARBOR! Figura 10.13: Stergerea unui nod (4) cu un singur fu. Legitura 2-3 “ocoleste" nodul 4 Figura 10.14: Stergerea unui nod eu doi fii. Cel mai mie nod din subarborele drept al lui2 este 3. Se inlocuiese 2 cu 3, dup’ care 3 se sterge prin “ocolire” 6 ARBOR care este adevirati cind subarborele curent este vid. in aceastsituaieelemen- tul x nu este gisit gi se ancl o TeemMot FoundExcept ic. acl subarborele nu este vid, se compari elementul care trebuie sles cu ri- Dac nodul curent nu are descendenti in ambele parti, operatia de stergere ‘este mult mai simp: pur si simplu se “urc8” subarborele nevid in locul nodului care a fost sters (altel spus, nodul sters este “ocolit”): ts (olen YP tteft stright: Metodele isEmpty () simakeZmpty () sunt banale gi nu le vom detalia Listing 10.21: Implementarea arborelui binar de clutare «package datastructures: MImport exceptions .+: i/se Arbore binar de coutare alocat inlantuit. Toate be cautarile se fac pe baza metodel compareTo( ). Expune te metode pentru inserare, stergere, caulare ete. +f ‘public class BinaryScarchTece, Implements SearchTree ut to fae Referinta catre redacina arboretui e/ protected BinaryNode root; 1 /eeConstructor care initializeaze radacina ew null +/ 5 public: BinarySearchTree() n 10S. ARBOR! fue Adauga clementul x in arbore © Gthrows DuplicateltemException daca elemental deja existe. «/ public void insect (Comparable x) throws DuplicateltemException i root = insert(x, root}: ) Jes Sterge clementul x din arbore + Gihrows NemNorFoundEsception daca clementul mu se afla : in arbore.4/ Public void remove(Comparable x) throws, emNotFoundE xeeption i root = remove(x, root): ) (ae slerse etemencat minim din arbore + Othrews ItewNotPoundEsception dace arborele este vid+/ Public void removeMin() throws. ItemNotFoundException c root = removeMin root ): ) fee Imoarce elemental minim din arbore + Gthrows MtemNotFoundbxception daca arborele este vids/ Public Comparable fiadMin() throws ItemNotFoundException i return fingMin( root). clement ) fos Intoorce elemental main din arbore + Othrews HtewNotFoundException dace arborele este vid+/ public Comparable findMax () throws ItemNotFoundEaception i return findMax( root). element: ) fee Canta elemental x tn arbore + Grhrows IemNotFoundException daca * mu este gasit.»/ publle Comparable find (Comparable x) throws, ItemNotFoundException return find(x, root)-element: ’ 105, ARBOR! 4 fee Intoarce true daca arborele este vid +/ S public boolean isEmpty () “f “1 % /esVideaza arborele, setand radacina la mull «/ 2 publte.vold makcEmpty() ni an % protected BinaryNode find (Comparable x, BinaryNode 1) > throws. ItemNotFoundException mt 0 while (C= mull) » ot a it (x.compareTo(t element) < 0) E i ® t= tert Hy else If (x.compareTo(t clement) > 0) t= cright: ) else = 4 . return ti //element gasit * ) sy % throw new ItemNotFoundException ("Element nega: a % protected BinaryNode fingMin(BinaryNode «) & throws. IemNotFoundException mt fe Uf (== mult) i vs) throw mew TtemNotFoundException ("Element negasit” ): my te while (tteft 1= mult) tert my 2» 10S. ARBOR! protected BinaryNode findMax (BinaryNode t) throws. ItemNotFoundException ira c throw new ItemNotFoundException ("Element negasit") > while (t.cight t= mult) jected. Bina throws, Duplica Node insert (Comparable x, BinaryNode 1) ItemException re i {= new BinaryNode(x, mull, null): , elec If (x.compareTo(t element) < 0) fi toleft = insert(x, te teft): ) else If (x.compareTo(t. clement) > 0) C toright = insert(x, toright)s > throw new DuplicateltemException("Elementul exista deja"): ) protected BinaryNode removeMin(BinaryNode 1) throws. ItemNotFoundException t ra i throw new ItemNotFoundException ("Element negasit"): ie (ietefe t= matty i tet nut) removeMin(t. ett): ARBOR rs ts torights m= . >) protected BinaryNode remove(Comparable x, BinaryNode t) be throws: ItemNotFoundException mae oS null) throw new ItemNotFoundException ("Element negasit”): ie th AF (x-compareTo(t element) < 0) mt ‘° toler my Ws else IF (x. compareTo(t element) > 0) mt emove(x, t. left): toright = romove(x, tight): 1 jae AE (4 left t= mal R&C right t= nal S| telement = findMin(t. eight). clement; me Coright = removeMin(t. right )s mt mo tle ™ ot we t= Cteet t= matty 2 tteet s tortene an mo : Listing 10.22 prezint& modul in care arborele binar de cdutare poate fi folosit pentru obiecte de tip String. Interfaja SearchTree mai are dou metode suplimentare: una pentru a sisi cel mai mic element si una pentru a gsi cel mai mare element. Se poate arita c& transpirdnd un pie mai mult se poate gisi foarte eficient gi cel mai mic al lea element, pentru oricare ktrimis ca parametru ‘S8 vedem care sunt timpii de executie pentru operafile pe un arbore bi- nar de clutare. Este normal si sperim c& timpii de execujie pentru £ind (), 81 10S. ARBOR! insert () si remove() si fie logaritmici, deoarece aceasta este valoarea pe care 0 vom objine pentru ciutarea binari (paragraful 12.3). Din nefericire, ‘pentru cea mai simpli implementare a arborelui binar de cdiutare, acest lueru nu este adevarat. Timpul mediu de execusie este intt-adevat logaritmic, dar in cazal, cel mai nefavorabil (cdnd arborele este “dezechilibrat”)timpul de executie este 0(n), caz care apare destul de frecvent. Totusi, prin aplicarea anumitor trucuri de algoritmic& se pot objine anumite structusi mai complexe (arbori bicolori) ‘care au intt-adevar un cost logaritmic pentru fiecare operatie. Listing 10.22: Model de program care utilizeazi arbori de efutare. Programul va afiga: Gisit CristisAlina nu a fost gisita import datastructures.+3 simport exceptions .¢: i/ee Clara simpla de test pentra arborii binari de causare. «/ lie class ‘TestSearchTree public state vold main(String [J args) i SearchTree { = new BinarySearehTree (): tring result = mull Sooty » ™ toinsert(* Cristi"): Boy ' €ateh(DuplicateltemException ¢) can soy > ony st e result = (String) ¢. find ("Cristi 3 System. out.print("Gasit " + result + * an) % cateh(ItemNotFoundException ¢) i % System. out, print ("Cristi mu a fost gasits » 4 yoy an ” result = (String) ¢, find ("Alina"); % System. out. print ("Gasit "+ result + * 5") an) > €ateh ItemNotFoundException e) 106. TABELE DE REPARTIZARE System-out.print("Alina nu a fost gasita;*) Ce putem spune despre operajile £indMin() si £indmax()? fn mod cer, acest operaii necestd un timp constant in cazulcButirii bina, deoarece implick doar accesarea unui element indicat. in cazul unui arbore binar de cutare aceste opera iau acelayi timp ca o ctutare obignuits, adic O (og 1) fn cazul mediu gi 0 (n) in eazul cel mai nefavorabil 10.6 Tabele de repartizare Existé foarte multe aplicayii care necesiti 0 clutare dinamie’ bazati doar pe un nume. O aplicajieclasici este tabela de simboluri a unui compilator. Pe ‘miisurk ce compileaza programul, compilatorul ebuie si rejin’i numele (impre- uni cu tipul, durata de viapi, locayia de memorie) tuturor identiicatorilor care au fost declaraji. Atunci cind vede un identificator in fara unei instrucfiuni de makempty Os = 5 /es Goleste tabela de repartizare, si elibereaza toate us referintete din tabloul elements. «/ lie void makeEmpty() a 5 currentSize = 0: % for (int i = 0; i < elements. length; +4) » ny elements fi) md > MN (ex Intoarce elementul cu chela x-hash) Xs @rhvows TemNorFoundException daca elementul mu ¢ gasit +/ public Hashable find (Hashable x) i throws. emNotFoundE xeeption mt fe Int currentPos = findPos (x): 2 assertPound(currentPos , “Element negasit): {return elements [curreatPos |. element oo DD fee Verifica daca elementul de pe potitia currensPos bf Grhrowe ItemNotFoundbxception in caz contrar +/ 87 106. TABELE DE REPARTIZARE vate vold assertFound(int currentPos , String mess throws, ItemNotFoundException ) if (elements [eurrentPos } == null II clements [eurrentPos |. isActive fl throw new ItemNotFoundException (message) false) ) Jus Sterge clementul x din tabela de repartizare Gthrows ltemNorFoundException daca x mee gasit. 4/ public vold remove(Hashable x) throws, ItemNotFoundException int currentPos = findPos (x): assertFound(curreatPos , "Element aegasit”) cclements [currentPos ].isActive = false: ) (fos Adauga clementul x tabelei de repertizare. Daca ste linge gradul de tncarcere marina adit te © dubleaza numarul de elemente din elements of public vold. insert (Hashable x) i Int currentPos = findPos (x) elements [currentPos ] = new HashEntry (x, true); if (s+ currentSize < elements length / 2) i Mdimensinnen tobstei este pree mice Wi" pot aparea conflicte, deel vom duble mumarul de elemente MashEmtry {] oléElements = elements: Wereara un tabel de dimensinne dubla elements = new HashEotry (oldElements. length } : currentSize = 0 “eople vechiul tabel in cel now for(int i= 0; 1 < oldElements length: i++) if (oldElements [i] != mull && oldBlements [i]. isActive) i insert (oldElements [i]. element 106. TABELE DE REPARTIZARE fee Asociaza un numar unic unei chei de tip String cu valoarea intre Osi tableSize—I. #/ toe public static Int hash(String Key, fat tableSize) int hashVal = 05, fe for Cint t= 0; 4 < key. length Qs 44) mt re hashVal = 37 « hash: an) hn hashVal hr Hf (hashVal < 0) mt te hashVal » return hashVals my bel + key chara (i): tablesizes tablesize: ProbingHashTable este clasa cea mai important in implementarea tunei tabele de repartizare. Ea implementeaza interfaja HashTable gi de- fineste toate operajiile expuse de aceasta. Elementele din tabela de repartizare sunt rejinute intrun sir de obiecte de tip HashEntry (atributul elements). Structura mai specifica de asemenea si numa de elemente care sunt stocate la ‘momental curent(atributul current Size), Inserarea unui element in tabela de repartizare presupune asocierea unui rnumar uni respectivului element, prin intermediul metodei hash(). Acest rnumir devine indicele elementului in sirul elements, motiv pentru care acce- sul in timp constant este asigurat. Practic, prin inserarea elementelor in tabela de repartizare, sil element's, care rejine aceste elemente, va fi populat intr tun mod discontinuu (elementele nu se vor afla pe pozitii suceesive, pentru ci pozijia lor depinde de valoarea lor). Cand se va face clutarea elementului, se va realiza operatia de hash () prin care se objine numlrul asociat, gi se va accesa direct elementul de pe pozifa calculati. Evident, accesul este in timp constant. ‘Metoda hash () calculeaz’i numiul asociat unui element pe baza unui al- goritm simplu, Se realizeazi o sumi de produse pe baza codului Unicode al flecirui caracter din cheia elementului care va fi inserat in tabel8, iar fn final se consider restul impirjirii acestei valori la dimensiunea tabelei, pentru ci 89 106. TABELE DE REPARTIZARE Listing 10.28: Clasa QuadraticProbingTable \ package datastructures: Jes Tabela eu repartizare patratica inchisa. Implementeaza meroda hs abstracta findPor() mostenita de la Probingiashtable +/ ipublic class QuadraticProbingTable extends ProbingHashTable © protected Int findPos (Hashable x) at 1 int collisionNum = 0: Sint currentPos = x.hash(array length ): white (array [euceeatPos | 1= mull && a array [curtemtPos ]. element. equals (x)) » i u collisionNum +4; a curtentPos += 2 + collisionNum — 1 e if (curventPos " ( * curremtPos > , arcay length) = array .Jength a return currentPos numeral asociat elementului trebuie si fie mai mic decét dimensiunea tabelei (numarul nu este altceva decdt un indice al girului element's). 10.6.1. Tratarea coliziunilor Este important si observim faptul ec metoda hash () nu ne asigura de faptul e& obiecte distince vor avea repartizari distince. De fapt, exist sanse considerable ca pentru doui elemente diferite, metoda hash () si returneze acelasi numit. Aceasta este o situafie inacceptabili, pentru ci nu putem avea dou elemente care si fie pe aceeasi pozitie in girul elements. Din acest motiv, avem nevoie de o strategie care si elimine coliziunile care pot si apard. Strategia va determina daci numirul asociat de metoda hash () este deja ocu- pat si va oferi un alt numir care nu a fost alocat anterior. Aceasta strategie va fi utilizat att in operatia de adugare, ct gin cea de ciutare a elementului 90 106. TABELE DE REPARTIZARE Exist mai multe strategii disponibile, care se bazeaza pe cutarea unui spajiu neocupat in sirul element's. De aici provine gi numele clasei Pro- bingHashTable. Cu alte cuvinte, in caz de coliziune, se probeazd ele- ‘mentele din sirul @Lement's, pana se descopers unul neocupat. Pentru a oferi suport pentru implementarea oricSrei strategii, am decis ca ProbingHashTable si declare abstract metoda care trateaza situaiile de coliziune (este vorba despre metoda £indPos ()), motiv pentru care si clasa devine abstract, urmand ca fiecare strategie si defineasciiaceasti metoda int-o clasi derivati separati. ‘Cea mai simpli strategie pentru evitarea coliziuni este probarea liniari, cu alte cuvinte ciutarea secvential (element cu element) in gir, pani se giseste © celuli goali, care si fie alocati elementului in cauzi. Performanta acestet strategii nu este ridicatS, mai ales in situajia fn care avem o tabel\ de dimensiuni strategie mai performanti este cea patraticd, in care cAutarea nu se face liniar (2, i + 1,4 + 2,4 + 3ete.),cain exemplul anterior, ci in "salturi” ‘mai maridetipul i, + 12,4 + 22,4 + SP ete, Acesta este motivul pentru care clasa care defineste metoda £indPos () poartii numele de Qua ProbingTable (quadratic == pitratic). Deoarec ‘mentul nu va fi pus pe pozifia data de funcyia de repartizare ci pe locayia liberi gisitt prin probare, clutarea unui element va trebui ficuti tot prin probare, deci tot utilizand metoda £indPos (), apelati la linia 40 in cadrul metodei find () dinclasa ProbingHashTable. Astfel, clutarea se va oprifie cand elementul este gist, fle cAnd s-a ajuns Ia o locatie goal in element s. O alti observajie important este cd stergerea unui element au va putea fi realizati prin setarea pozifici care fi corespunde in eLements la nu11, deoarece aceasta va ‘impiedica gasirea elementelor cu aceeasi valoare a funcjiei de repartizare care ‘au fost agezate prin probare dupa elementul sters. Acesta este motivul pen- mu care slergetea unui element se face prin setarea atributului isAct ive la false. Listing 10.29 prezinta un exemplu de utlizare al tabelei de repartizare, Exist foarte multe modalitiji de a implementa tabelele de repartizare. Noi ‘am prezentat aici doar una singur, numité repartizare pitraticd inchis’. Pentru © detalii referitoare la acest subiect recomandiim excelenta lucrare Data Siruc- ‘ures (vezi [Tomescu)) tice cexzul unit conflict, ele Listing 10.29: Exempla de program care foloseste tabele de repartizare; pro- gramul va afga: Gasit Marcel Import datastructures Himport exceptions -+ 91 107. COZ DE PRIORITATE mpla de test pentru tabelele de repartizare. +/ '¢ TestHashTable ales Clas ‘public public static void main(String [] args) ew QuadratieProbingTable () tS Hashtable 0 MyString result = null: th hoimsert (mew MyString(*Marcel"))s ot eesult = (MyString ) h. find (new MyString ("Mareel")) System. out. printin("Gasit "+ result): Hoy eaten (IlemNotFoundException e) » 1 s System out. printla Marcel nu a fost gasit"); > 10.7 Cozi de prioritate ‘Si pornim de la o problema concreti extrem de simpli: ordinea de tiparire 4 documentelor la © imprimanta partajata, in cadrul unei refele, de un numair mare de utilizatori. In mod obisnuit documentee trimise unei imprimante sunt agezate, int-o coada simpld, dar aceasta nu este intotdeauna cea mai bun’ vari- anti, De exemplu, un document poate si fie deosebit de important, deci el ar trebui executat imediat ce imprimanta este disponibila. De asemenea, dacd imprimanta a terminat de tiparit un document, iar in coada se alfa citeva do- ‘cumente avind 1-2 pagini si un document avind 100 de pagini, ar fi normal ‘ea documentul lung si fie tiparit ulimul, chiar daci nu este ultimul document Analog, in cazul unui sistem multiutilizator, sistemul de operare trebuie si 0. t ) percolateDown (i); orderOK, 1 Jes Piltreaza elemental de pe positia hole axezan ‘+ subarborele cu radacina hole lo leew! euvenit. +7 private vold percolateDown (Int hole) ‘ int child: Comparable imp = elements (hole }: while(hole + 2 <= currentSize) 101 wt ' child = hole + 25 ho it (Cohild t= currentSize && rs elements child + I].compareTo(elements [child ]) < 0) S fl oS child es, ™ bo if (elements {child ].compareTo(imp) < 0) mf 5 elements [hole] = elements [ehild]s eS ) 5 else = i wm break: wo ) me hale = ehitd my vb» elements [hole] = tmp: my to fee Sterge clementul minim (flat pe positia I!) si to + apeleaza algoritmul de filirare pentru a reface ansamblul tu + Gthrows UnderflowException daca ansamblul este vid. +/ 1 public Comparable deleteMin() throws UnderflowException mt 1 Comparable minliem = findMin(s tw elements (1] = elements {currentSize—— ts percolateDowa (1); 9) return minttem; my tm es true daca ansamblul este vid +/ my return currentSize ta /e4 Goleste ansamblut setend dimensiunea la O+/ 9 publle. void makeEmpty() mt ti curremtSize = 0; my oD 107. Coz DE PRIORITATE Pentra a testa ansamblul, am creat urmitorul exemplu simplu: Listing 10.32: Exemplu de utilizare a unei coz de prioritii, Programul va afisa: Continutul ansamblului: 0123.4 import datastructures = dimport exceptions + t/a Clasa de 16st simpla pentru coz de prioritare. +/ Spublic class TestPriority Queve “at 1 public static void main( Si 20) ares) lorityQueue pg = new BinaryHeap( * new Integer(Integer -MIN_VALUE}): mPa Integer (4))5, » pa nteger(2))5 he pqvinsert (new Integer (1)): % pqcinsert (new Integer (3): “ pacinsert (new Integer (0)}: ' System.out.print("Continutul ansamblului uy » Ber css) fi 5 System. out. print (pq. deleteMin () +" uy sy % cateh(UnderflowException e) > sy = ”) Rezumat ‘Am prezentat pe scurt in cadrul acestui capitol cele mai importante steuctusi de date uilizate de programatori in practicd. Fiecare structuré de date oferi o interfaji clari cu toate operajile pe care le permite, implementarea ei putind fi ficutd in mai multe moduri. Stiva i coada sunt structuri de date elementare, ‘care ofer operaji de adaugare respectiv stergere la un singur capat in timp ‘constant, Listele inkinguite permit operajii de adiugare si stergere arbitrae $i ‘au avantajul faja de siruric& inserarea unui element nu implica deplasarea ele- mentelor alate la dreapta. Arborii binari de clutare permit inserarea, cdtuarea 103 107. COZ DE PRIORITATE: si stergerea fn timp logaritmic. Ei oferd de asemeni o modaltate de a parcurge in ordine elementele conjinute. Tabetele de eparizare permit o implementare extrem de efcienti a operailo de inserare si egisire. I sii, cove de pri- ortate permit opera supra elementului minim (sau maxim) din cadralstruc- turf timp fogartmic, Ele au avantajl fala de arbor binar (care permits ei acelag cra) c& sunt mai simplo de implementat si nu implicit reinerea de legituri cite fi din stanga si dreapta, Stricture de dae reprezineo disciplina de sine stittoare, iar noi nu am putt aici decit si oferimo introducerein acest domeniv, Cei are doresc safle mai molte sont invitais&parcerga [Tomescu) $i {Cormen} fncepand cu urmatoral capitol, vor fi prezenate metodelefundamentale de elaborate a algortmior. Prima dintre ele este metoda cAutri cu revenie (back- tracking). Nofiuni fundamentale ansamblu binar: o varianti de arbore binar complet in care un nod este fie ‘mai mic fie mai mare dec fit si. arbore: structuri de date formati dintr-o multime de noduri gi muchit (fo- losite pentna a lega nodurile intr ele) astfel inedt nu existd noduri eare nu sunt legate direct sau indirect i nu se pot realizacireuite ‘arbore binar: arbore in care ficcare nod are cel mult doi fi, arbore binar de cutare: varianti de arbore binar care suport eficient operajii de adaugare, stergere si ciutare, Fiul din stinga este mai mic decit Parintele, iar ful din dreapta este mai mare. clasi iterator: tip de clasi care permite manipularea unei liste ‘coadi: structurd de date care permite accesul doar la cel mai vechi element adiugat coadii de prioritifi:structuri de date care permite accesul doar la elemen- tul eel mai mi frunzi: inte-un arbore, reprezinti un nod fia fi funetie hash: functie care caleuleaza pe baza unui obiect primit, un intrez care va fi asociat cu obiectul respectiv. Doar obiectele care implementeaza in- terfaja Hashable pot fi folosite de aceasta functic stivi structura de date care permite accesul doar la cel mai recent element inserat. structurd de date: o reprezentare a unor date si a operasillor pe acele date. Prin intermediul structurior de date se poate objine reutilizarea componentelor. tabelii de repartizare (hashtable): structuride date care permite adiugai, stergeri si ciutaei inte-un timp mediu constant. 108 Erori freevente I. Se consider eroare, incercarea de a accesa sau sterge elemente in cazul in care stiva, coada sau coada de priorititi sunt vide. 2. O coadi de priortaji nu are nici o legituri cu 0 coada. Este doar o coin- ceidengé de nume. 3. Funcfia hash () pentru o tabeld de repartizare returneaziio valoare de tip nt. Este posibil cain timpul calculelor intermediare si se produc de- piri, agadar este necesar si se verifice ca rezultatul operatorului modulo si fie pozitiv. 4, Performanya unei tabele de repartizare se degradeazi semnificativ pe mi surlice factorul de incdrcare se apropie de 1.0. Mari dimensiunea tabelei de indata ce factorul de incdrcare a atins valoarea 0.5 Exercitii Pescurt Aritati care sunt rezultatele urmitoarei secvente de operati: adauga (6) , adauga(12), adauga(2), adauga(7), sterge(), ster ge () in cazul in care operatille adauga() si sterge() corespund ‘operatillor de baz’ pentru: (a) stivas (6) coada; (©) arbore binar de ciutare; (@) coada de priori 2, Desenafi arborii binari de citutare de de chei (1,5, 8,9, 12, 17,29)! a 5 s16 pentru muljimea 3. Scrieti ordinea nodurilor rezultata pentru parcurgerea in preordin« dine si postordine a arborilor de clutare de Ia exercitiul precedent, 4. Si presupunem ci avem numerele de la I la 1000 fntrsun arbore binar de clutare si ci dorim si cutim numarul 363. Care dintre urmatoarele seevenfe nu poate constitui o seeven{a de noduri examinate? (a) 2,252, 401, 398, 330, 344, 397, 363; 105 107. COZ DE PRIORITATE (b) 924, 220, 911, 244, 898, 258, 362, 363; (©) 925, 202, 911, 240, 912, 245, 363; (@) 2, 399, 387, 219, 266, 382, 381, 278, 363; (e) 935, 278, 347, 621, 299, 392, 358, 363. 45, Desenai ansamblal care rezults in urma inseririi elementelor 47, 28, 19, 6,15, 12,3, 5,9, 14 fnte-un ansambluinigial vid! Teorie 1, S& presupunem c& am implementa coada din paragraful 10.3 far a aseza clementele circular. Gasiti o seeventa de operafi, care repetat la infnit ‘conduce la maitea nedefinitda tabloului elements, chiar daci in coada sunt doar edteva elemente. 2. Si presupunem cd dorim o structuri de date care si suporte doar uemii- toarele operaji: addugare, gdsirea maximului si stergerea maximului. Cat, de eficient pot fiimplementate aceste operatii? Indicafie: Se utlizeaza un ansamblu in care ridicina este mai mare decat, fii. 43. Existi o posibilitate de a implementa urmitoarele operafi in timp logarit- mic in cadrul aceleiagi structuri de date: gisire minim si maxim, stergere ‘minim si maxim, adaugare? Indicatie: Se utilizeaza un arbore binar de cdutare, 4. Exist posibitatea de @ implementa urmatoarele operat in timp con- stant: push, pop si gisirea minimului? Indicafie: Se observ ci nu se cere gi stergerea minimului. Putem astfel utiliza dous stive, una care refine clementele structurii de date, iar alta ‘care refine valorile minime, 5. De ce in cazul metodei findMin() din clasa BinarySearchTree nu a fost nevoie sa salvim valoarea parametrului t, care este modificat de cdtre metodi? 6. Profesonul Stietot are impresia ci a descoperit o proprietate remarcabil 1 arborilor de ciutare. Si presupunem ci o e&utare pentru cheia k intt- un arbore de edularese termin’ int-o frunzi. Considerim urmitoarele ‘muljimi: A: nodurile din stanga drumului parcurs pind la k, B: muljimea rodurilor aflate chiar pe acest drum si C, muljimea cheilor din dreapta 106 107. Coz DE PRIORITATE

You might also like