Sunteți pe pagina 1din 896

Titlul original: Introduction to Algorithms

c 1990 Massachusetts Institute of Technology


Copyright

Editor coordonator: Clara Ionescu


Coordonator traducere: Horia F. Pop
Traducere:
Prefaa: Simona Motogna Capitolul 19: Florian M. Boian
Capitolul 1: Horia F. Pop Capitolul 20: Ioan Lazar
Capitolul 2: Paul Blaga Capitolul 21: Ioan Lazar
Capitolul 3: Paul Blaga Capitolul 22: Virginia Niculescu
Capitolul 4: Paul Blaga Capitolul 23: Adrian Monea
Capitolul 5: Adrian Monea Capitolul 24: Adrian Monea
Capitolul 6: Radu Trmbia Capitolul 25: Luminia State
Capitolul 7: Clara Ionescu Capitolul 26: Mihai Scoraru
Capitolul 8: Zoltn Ksa Capitolul 27: Zoltn Ksa, Simona Motogna
Capitolul 9: Luminia State Capitolul 28: Zoltn Ksa
Capitolul 10: Luminia State Capitolul 29: Florian M. Boian
Capitolul 11: Simona Motogna Capitolul 30: Mihai Scoraru
Capitolul 12: Simona Motogna Capitolul 31: Liviu Negrescu
Capitolul 13: Bazil Prv Capitolul 32: Radu Trmbia
Capitolul 14: Bazil Prv Capitolul 33: Liviu Negrescu
Capitolul 15: Bazil Prv Capitolul 34: Liana Bozga
Capitolul 16: Cristina Vertan Capitolul 35: Liana Bozga
Capitolul 17: Cristina Vertan Capitolul 36: Mihai Scoraru
Capitolul 18: Cristina Vertan Capitolul 37: Horia F. Pop
Lecturare:
Florian M. Boian, Liana Bozga, Carmen Bucur, Ioana Chiorean, Horia Georgescu,
Clara Ionescu, Eugen Ionescu, Zoltn Ksa, Ioan Lazar, Adrian Monea, Simona Motogna,
Virginia Niculescu, Bazil Prv, Horia F. Pop, Mihai Scoraru, Radu Trmbia
Index: Simona Motogna

Grafica: Dan Creu

Coperta: Mircea Drgoi

Au confruntat cu originalul:
Carmen Bucur, Clara Ionescu, Simona Motogna, Drago Petracu
Filolog: cerc. princ. Ileana Cmpean
Copyright c Ediia n limba romn Computer Libris Agora
ISBN 973-97534-7-7
Cuprins

Prefaa ediiei n limba romn ix

Prefa xi

1. Introducere 1
1.1. Algoritmi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2. Analiza algoritmilor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.3. Proiectarea algoritmilor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.4. Rezumat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

I. Fundamente matematice 18

2. Creterea funciilor 20
2.1. Notaia asimptotic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.2. Notaii standard i funcii comune . . . . . . . . . . . . . . . . . . . . . . . . . . 28

3. Sume 37
3.1. Formule de nsumare i proprieti . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3.2. Delimitarea sumelor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

4. Recurene 46
4.1. Metoda substituiei . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
4.2. Metoda iteraiei . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
4.3. Metoda master . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.4. Demonstraia teoremei master . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

5. Mulimi etc. 66
5.1. Mulimi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
5.2. Relaii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
5.3. Funcii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
5.4. Grafuri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
5.5. Arbori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
iv Cuprins

6. Numrare i probabilitate 86
6.1. Numrare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
6.2. Probabilitate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
6.3. Variabile aleatoare discrete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
6.4. Distribuia geometric i distribuia binomial . . . . . . . . . . . . . . . . . . . 100
6.5. Cozile distribuiei binomiale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
6.6. Analiz probabilistic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

II. Ordonare i statistici de ordine 116


7. Heapsort 119
7.1. Heap-uri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
7.2. Reconstituirea proprietii de heap . . . . . . . . . . . . . . . . . . . . . . . . . . 121
7.3. Construirea unui heap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
7.4. Algoritmul heapsort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
7.5. Cozi de prioriti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126

8. Sortarea rapid 131


8.1. Descrierea sortrii rapide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
8.2. Performana algoritmului de sortare rapid . . . . . . . . . . . . . . . . . . . . . 133
8.3. Variantele aleatoare ale sortrii rapide . . . . . . . . . . . . . . . . . . . . . . . . 137
8.4. Analiza algoritmului de sortare rapid . . . . . . . . . . . . . . . . . . . . . . . . 139

9. Sortare n timp liniar 147


9.1. Margini inferioare pentru sortare . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
9.2. Sortarea prin numrare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
9.3. Ordonare pe baza cifrelor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
9.4. Ordonarea pe grupe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154

10.Mediane i statistici de ordine 158


10.1. Minim i maxim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
10.2. Selecia n timp mediu liniar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
10.3. Selecia n timp liniar n cazul cel mai defavorabil . . . . . . . . . . . . . . . . . . 161

III. Structuri de date 167


11.Structuri de date elementare 171
11.1. Stive i cozi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
11.2. Liste nlnuite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
11.3. Implementarea pointerilor i obiectelor . . . . . . . . . . . . . . . . . . . . . . . . 178
11.4. Reprezentarea arborilor cu rdcin . . . . . . . . . . . . . . . . . . . . . . . . . 182

12.Tabele de dispersie 187


12.1. Tabele cu adresare direct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
12.2. Tabele de dispersie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
12.3. Funcii de dispersie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
Cuprins v

12.4. Adresarea deschis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198

13.Arbori binari de cutare 208


13.1. Ce este un arbore binar de cutare? . . . . . . . . . . . . . . . . . . . . . . . . . 208
13.2. Interogarea ntr-un arbore binar de cutare . . . . . . . . . . . . . . . . . . . . . 210
13.3. Inserarea i tergerea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
13.4. Arbori binari de cutare construii aleator . . . . . . . . . . . . . . . . . . . . . . 217

14.Arbori rou-negru 226


14.1. Proprietile arborilor rou-negru . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
14.2. Rotaii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
14.3. Inserarea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
14.4. tergerea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234

15.mbogirea structurilor de date 243


15.1. Statistici dinamice de ordine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
15.2. Cum se mbogete o structur de date . . . . . . . . . . . . . . . . . . . . . . . 248
15.3. Arbori de intervale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251

IV. Tehnici avansate de proiectare i analiz 257


16.Programarea dinamic 259
16.1. nmulirea unui ir de matrice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
16.2. Elemente de programare dinamic . . . . . . . . . . . . . . . . . . . . . . . . . . 266
16.3. Cel mai lung subir comun . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
16.4. Triangularea optim a poligoanelor . . . . . . . . . . . . . . . . . . . . . . . . . . 275

17.Algoritmi greedy 283


17.1. O problem de selectare a activitilor . . . . . . . . . . . . . . . . . . . . . . . . 283
17.2. Elemente ale strategiei greedy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
17.3. Coduri Huffman . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
17.4. Bazele teoretice ale metodei greedy . . . . . . . . . . . . . . . . . . . . . . . . . . 296
17.5. O problem de planificare a activitilor . . . . . . . . . . . . . . . . . . . . . . . 301

18.Analiza amortizat 306


18.1. Metoda de agregare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
18.2. Metoda de cotare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310
18.3. Metoda de potenial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
18.4. Tabele dinamice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315

V. Structuri de date avansate 325


19.B-arbori 328
19.1. Definiia B-arborelui . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
19.2. Operaii de baz n B-arbore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
19.3. tergerea unei chei dintr-un B-arbore . . . . . . . . . . . . . . . . . . . . . . . . . 339
vi Cuprins

20.Heap-uri binomiale 344


20.1. Arbori binomiali i heap-uri binomiale . . . . . . . . . . . . . . . . . . . . . . . . 345
20.2. Operaii pe heap-uri binomiale . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349

21.Heap-uri Fibonacci 362


21.1. Structura heap-urilor Fibonacci . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363
21.2. Operaiile heap-urilor interclasabile . . . . . . . . . . . . . . . . . . . . . . . . . . 364
21.3. Descreterea unei chei i tergerea unui nod . . . . . . . . . . . . . . . . . . . . . 372
21.4. Mrginirea gradului maxim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374

22.Structuri de date pentru mulimi disjuncte 379


22.1. Operaii pe mulimi disjuncte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379
22.2. Reprezentarea mulimilor disjuncte prin liste nlnuite . . . . . . . . . . . . . . . 381
22.3. Pduri de mulimi disjuncte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384
22.4. Analiza reuniunii dup rang comprimnd drumul . . . . . . . . . . . . . . . . . . 388

VI. Algoritmi de grafuri 398


23.Algoritmi elementari de grafuri 400
23.1. Reprezentrile grafurilor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400
23.2. Cutarea n lime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403
23.3. Cutarea n adncime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 410
23.4. Sortarea topologic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417
23.5. Componente tare conexe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420

24.Arbori de acoperire minimi 428


24.1. Dezvoltarea unui arbore de acoperire minim . . . . . . . . . . . . . . . . . . . . . 429
24.2. Algoritmii lui Kruskal i Prim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433

25.Drumuri minime de surs unic 441


25.1. Drumuri minime i relaxare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445
25.2. Algoritmul Dijkstra . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452
25.3. Algoritmul Bellman-Ford . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456
25.4. Drumuri minime de surs unic n grafuri orientate aciclice . . . . . . . . . . . . 460
25.5. Constrngeri cu diferene i drumurile minime . . . . . . . . . . . . . . . . . . . . 462

26.Drumuri minime ntre toate perechile de vrfuri 473


26.1. Drumuri minime i nmulirea matricelor . . . . . . . . . . . . . . . . . . . . . . . 475
26.2. Algoritmul Floyd-Warshall . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 480
26.3. Algoritmul lui Johnson pentru grafuri rare . . . . . . . . . . . . . . . . . . . . . . 486
26.4. O modalitate general pentru rezolvarea problemelor de drum n grafuri orientate 490

27.Flux maxim 498


27.1. Reele de transport . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 498
27.2. Metoda lui Ford-Fulkerson . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505
27.3. Cuplaj bipartit maxim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515
Cuprins vii

27.4. Algoritmi de preflux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519


27.5. Algoritmul mutare-n-fa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 527

VII. Capitole speciale 541


28.Reele de sortare 544
28.1. Reele de comparare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544
28.2. Principiul zero-unu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 548
28.3. O reea de sortare a secvenelor bitone . . . . . . . . . . . . . . . . . . . . . . . . 550
28.4. Reeaua de interclasare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 552
28.5. Reeaua de sortare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 555

29.Circuite aritmetice 561


29.1. Circuite combinaionale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 561
29.2. Circuite de sumare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 566
29.3. Circuite multiplicatoare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 575
29.4. Circuite cu ceas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 581

30.Algoritmi pentru calculatoare paralele 590


30.1. Saltul de pointer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 593
30.2. Algoritmi CRCW i algoritmi EREW . . . . . . . . . . . . . . . . . . . . . . . . 601
30.3. Teorema lui Brent i eficiena efortului . . . . . . . . . . . . . . . . . . . . . . . . 608
30.4. Calculul paralel de prefix, eficient ca efort . . . . . . . . . . . . . . . . . . . . . . 612
30.5. ntreruperi deterministe de simetrie . . . . . . . . . . . . . . . . . . . . . . . . . . 617

31.Operaii cu matrice 626


31.1. Proprietile matricelor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 626
31.2. Algoritmul lui Strassen pentru nmulirea matricelor . . . . . . . . . . . . . . . . 633
31.3. Sisteme de numere algebrice i nmulirea matricelor booleene . . . . . . . . . . . 638
31.4. Rezolvarea sistemelor de ecuaii liniare . . . . . . . . . . . . . . . . . . . . . . . . 642
31.5. Inversarea matricelor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 653
31.6. Matrice simetrice pozitiv-definite i aproximarea prin
metoda celor mai mici ptrate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 657

32.Polinoame i TFR 666


32.1. Reprezentarea polinoamelor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 667
32.2. TFD i TFR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 673
32.3. Implementri eficiente ale TFR . . . . . . . . . . . . . . . . . . . . . . . . . . . . 679

33.Algoritmi din teoria numerelor 687


33.1. Noiuni elementare de teoria numerelor . . . . . . . . . . . . . . . . . . . . . . . 688
33.2. Cel mai mare divizor comun . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 693
33.3. Aritmetic modular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 697
33.4. Rezolvarea ecuaiilor liniare modulare . . . . . . . . . . . . . . . . . . . . . . . . 702
33.5. Teorema chinez a restului . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 705
33.6. Puterile unui element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 708
viii Cuprins

33.7. Criptosistemul RSA cu cheie public . . . . . . . . . . . . . . . . . . . . . . . . . 711


33.8. Testul de primalitate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 717
33.9. Factorizarea ntreag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 724

34.Potrivirea irurilor 731


34.1. Algoritmul naiv pentru potrivirea irurilor . . . . . . . . . . . . . . . . . . . . . . 732
34.2. Algoritmul Rabin-Karp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 735
34.3. Potrivirea irurilor folosind automate finite . . . . . . . . . . . . . . . . . . . . . 739
34.4. Algoritmul Knuth-Morris-Pratt . . . . . . . . . . . . . . . . . . . . . . . . . . . . 745
34.5. Algoritmul Boyer-Moore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 751

35.Geometrie computaional 759


35.1. Proprietile segmentului de dreapt . . . . . . . . . . . . . . . . . . . . . . . . . 759
35.2. Determinarea cazului n care oricare dou segmente se intersecteaz . . . . . . . 764
35.3. Determinarea nvelitorii convexe . . . . . . . . . . . . . . . . . . . . . . . . . . . 769
35.4. Determinarea celei mai apropiate perechi de puncte . . . . . . . . . . . . . . . . . 778

36.NP-completitudine 785
36.1. Timpul polinomial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 786
36.2. Verificri n timp polinomial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 792
36.3. NP-completitudine i reductibilitate . . . . . . . . . . . . . . . . . . . . . . . . . 796
36.4. Demonstraii ale NP-completitudinii . . . . . . . . . . . . . . . . . . . . . . . . . 804
36.5. Probleme NP-complete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 810

37.Algoritmi de aproximare 826


37.1. Problema acoperirii cu vrfuri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 828
37.2. Problema comis-voiajorului . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 830
37.3. Problema acoperirii mulimii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 834
37.4. Problema sumei submulimii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 838

Bibliografie 845

Index 853
Prefaa ediiei n limba romn

Stimai cititori,
Ani de zile am visat apariia acestei cri. tiu c muli profesori, elevi i studeni au cutat
lucrarea semnat de Thomas H. Cormen, Charles E. Leiserson i Ronald L. Rivest n original
sau diverse traduceri ale ei. Unii, mai norocoi, au reuit poate s mprumute cartea din diverse
locuri, pentru scurte perioade de timp. Dar aceast carte conine un volum foarte mare de
cunotine i nu este suficient s o rsfoieti ntr-un sfrit de sptmn, ci este nevoie de luni,
poate ani, pentru a putea asimila toate informaiile cuprinse ntr-o lucrare ca aceasta.
Primul contact cu MIT Press l-am stabilit n toamna anului 1998. Mulumim doamnei
Cristina Sanmartin (MIT Press) c ne-a ncurajat i a intermediat semnarea contractului
pentru traducere i editare n limba romn. Acum suntem deja n 2000. A durat traducerea,
tehnoredactarea i tiprirea. Pentru apariia n limba romn a crii, adresez mulumiri
profesorilor de la Universitatea Babe-Bolyai i de la Universitatea Bucureti, studenilor i
prietenilor care au sacrificat multe ore din timpul lor liber, pentru ca dumneavoastr s putei
ine aceast carte n mn.
Domnul confereniar dr. Horia F. Pop, de la Universitatea Babe-Bolyai, Facultatea de
Matematic i Informatic, a coordonat traducerea, a stabilit mpreun cu traductorii modul
de traducere a termenilor de specialitate noi, ncepnd cu index-ul, pentru a asigura o traducere
coerent, omogen i pe ct posibil unitar. De asemenea, a pregtit i coordonat utilizarea de
ctre traductori a sistemului LATEX.
Am lucrat cu cadre didactice universitare de specialitate deoarece o asemenea carte nu se
traduce doar cu lingviti, este nevoie de specialiti din domeniu care neleg foarte bine coninutul
tiinific i sunt de acord s reformuleze anumite pri pentru a exprima ceea ce de fapt autorul
a dorit s comunice. Mulumim domnilor (n ordine alfabetic) lector dr. Paul Blaga, profesor
dr. Florian Mircea Boian, drd. Liana Bozga, profesor dr. Zoltn Ksa, lector drd. Ioan Lazar,
lector drd. Simona Motogna, asistent drd. Virginia Niculescu, profesor dr. Bazil Prv, lector dr.
Radu Trmbia, de la Universitatea Babe-Bolyai din Cluj, domnului profesor Liviu Negrescu
de la Universitatea Tehnic din Cluj, domnului profesor dr. Horia Georgescu de la Academia de
Studii Economice, doamnei profesor dr. Luminia State de la Universitatea din Piteti, doamnei
lector drd. Cristina Vertan, de la Universitatea Bucureti i nu n ultimul rnd studenilor Adrian
Monea i Mihai Scoraru, de la Universitatea Tehnic din Cluj.
Cum aceasta este prima carte editat de Computer Libris Agora n LATEX, tehnoredactarea
a constituit i ea un efort. n special pregtirea desenelor a ridicat multe probleme, graficianul
x

nostru Dan Creu lucrnd nenumrate ore la realizarea acestora. Asistena tehnic n domeniul
pregtirii pentru tipar a fost acordat de Mihai Uricaru.
ntr-o carte de asemenea dimensiuni i complexitate cu siguran se strecoar i unele greeli.
Am dori ca acestea s fie eliminate din viitoarele ediii ale lucrrii. Din acest motiv, v rugm
s ne transmitei observaiile i sugestiile dumneavoastr pe adresa de e-mail:
clara@cs.ubbcluj.ro
sau pe adresa editurii:
Editura Computer Libris Agora
Str. Universitii nr. 8
3400 Cluj Napoca
Tel.: 064-192422
Urmnd exemplul american, lista cu greelile gsite va fi disponibil pe Internet. Cei care
doresc s intre n posesia ultimei erate pot trimite un mesaj la adresa algoritmi@agora.ro
coninnd expresia erata algoritmi n cmpul Subject i vor primi automat ultima versiune n
format electronic. Alternativ, putei vizita pagina
http://www.libris.agora.ro/algoritmi/erata.html.
Autorii, aa cum am aflat de la MIT Press, lucreaz la o versiune nou a crii, revizuit i
mbogit. V promitem c, imediat ce aceast versiune va fi disponibil pentru traducere, o
vom publica i n limba romn.

Cluj, 28 martie 2000

Clara Ionescu, editor coordonator


Prefa

Aceast carte se dorete a fi o introducere exhaustiv n studiul modern al algoritmilor. Ea


prezint muli algoritmi i i studiaz n profunzime, pstrnd totui analiza i proiectarea lor la
un nivel accesibil tuturor cititorilor. Am ncercat s pstrm explicaiile la un nivel elementar
fr a afecta profunzimea abordrii sau rigoarea matematic.
Fiecare capitol prezint un algoritm, o tehnic de proiectare, o arie de aplicare sau un
subiect legat de acestea. Algoritmii sunt descrii n englez i n pseudocod, care a fost astfel
conceput nct s poat fi neles de oricine care posed cunotiine elementare de programare.
Cartea conine peste 260 de figuri, care ilustreaz modul de funcionare a algoritmilor. Deoarece
considerm eficiena ca un criteriu de baz n proiectare, vom include analiza atent a timpilor
de execuie a algoritmilor prezentai.
Cartea se adreseaz, n primul rnd, celor care studiaz un curs elementar sau academic de
algoritmi sau structuri de date. Deoarece studiaz att aspecte tehnice, ct i matematice n
proiectarea algoritmilor, este la fel de binevenit pentru profesionitii autodidaci.

Pentru profesori
Aceast carte a fost conceput pentru a fi att multilateral ct i complet. O vei gsi util
pentru diverse cursuri, de la un curs elementar de structuri de date pn la un curs academic
de algoritmi. Deoarece am adunat considerabil mai mult material dect poate ncpea ntr-un
curs obinuit de un semestru, cartea poate fi privit ca un depozit din care se poate alege
materialul cel mai adecvat cursului care urmeaz s fie prezentat.
Vi se va prea uor s v organizai cursul doar pe baza capitolelor care v sunt necesare.
Am conceput capitolele relativ de sine stttoare, astfel nct s nu depindei n mod neateptat
sau inutil de informaii din alte capitole. Fiecare capitol prezint la nceput noiunile mai simple
i apoi, cele mai dificile, partiionarea pe seciuni mrginind n mod natural punctele de oprire.
Pentru un curs elementar se pot folosi doar primele seciuni dintr-un capitol; pentru un curs
avansat se poate parcurge ntreg capitolul.
Am inclus peste 900 de exerciii i peste 120 de probleme. Fiecare seciune se ncheie cu
exerciii, iar fiecare capitol cu probleme. Exerciiile sunt, n general, ntrebri scurte care testeaz
stpnirea noiunilor de baz prezentate. Unele dintre ele sunt simple verificri, n timp ce altele
sunt potrivite ca teme de cas. Problemele reprezint studii de caz mult mai elaborate, care de
multe ori introduc noiuni noi; n general, constau din mai multe ntrebri care conduc studentul
prin paii necesari pentru a ajunge la o soluie.
Am notat cu (*) seciunile i exerciiile care se adreseaz mai degrab studenilor avansai
dect celor nceptori. O seciune marcat cu (*) nu este n mod necesar mai dificil dect
xii Prefa

una obinuit, dar poate necesita nelegerea unor noiuni matematice mai complexe. n mod
asemntor, exerciiile marcate cu (*) pot necesita cunotine mai avansate sau creativitate mai
mult dect medie.

Pentru studeni
Sperm ca textul acestei cri s ofere o introducere plcut n domeniul algoritmilor. Am
intenionat s prezentm fiecare algoritm ntr-o manier accesibil i interesant. Pentru a fi un
ajutor cnd ntlnii algoritmi neobinuii sau dificili, am descris fiecare algoritm pas cu pas.
De asemenea, am oferit explicaii detaliate a noiunilor matematice necesare nelegerii analizei
algoritmilor. Dac deja dispunei de cunotine relative la un anumit subiect, atunci vei gsi
capitolele organizate astfel nct putei frunzri seciunile introductive i s v concentrai asupra
noiunilor mai complexe.
Fiind o carte vast, e posibil ca ceea ce vi se pred s acopere doar o parte a acestui material.
Oricum, ne-am strduit s construim aceast carte util i ca suport de curs, i ca o referin
teoretic i pratic n cariera voastr viitoare.
Care sunt cerinele pentru a nelege aceast carte?

Este necesar o anumit experien de programare. n particular, trebuie s nelegei


procedurile recursive i structurile de date simple, ca tablouri sau liste nlnuite.

Este necesar o anumit experien n demonstraii prin inducie matematic. Unele


poriuni din carte se bazeaz pe anumite cunotine de calcul elementar. n afar de asta,
partea nti a acestei cri v prezint toate tehnicile matematice necesare.

Pentru profesioniti
Aria larg de subiecte prezentate n aceast carte o recomand ca un excelent manual de
algoritmi. Deoarece fiecare capitol este conceput relativ independent, v putei concentra doar
asupra subiectelor care v intereseaz.
Majoritatea algoritmilor luai n discuie au o mare aplicabilitate practic. Din acest motiv,
lum n studiu i aspecte legate de implementare i alte probleme inginereti. n general, am
propus alternative practice puinilor algoritmi care prezint interes primordial teoretic.
Dac dorii s implementai oricare dintre algoritmi, vei constata c transcrierea algortimilor
din pseudocod n limbajul de programare preferat este o sarcin relativ uoar. Limbajul
pseudocod este astfel proiectat nct s prezinte fiecare algoritm ntr-un stil clar i concis.
n consecin, nu lum n considerare tratarea erorilor sau alte aspecte tehnice care necesit
presupuneri specifice relative unor medii de programare. Am urmrit s prezentm fiecare
algoritm simplu i direct, fr a ne opri asupra detaliilor relative la limbaje de programare.

Erori
O carte de asemenea dimensiune este n mod cert supus erorilor i omisiunilor. Dac
descoperii o eroare sau avei unele sugestii constructive, am aprecia s ni le mprtii. Sunt
binevenite, n mod special, sugestii pentru noi exerciii i probleme, dar v rugm s includei i
soluiile. Le putei trimite prin pot, pe adresa:
xiii

Introduction to Algorithms
MIT Laboratory for Computer Science
545 Technology Square
Cambridge, Massachusetts 02139
Sau, putei folosi pota electronic pentru a semnala erori, pentru a cere o erat sau pentru a
face sugestii constructive. Pentru a primi instruciunile de rigoare, trimitei un mesaj pe adresa
algorithms@theory.lcs.mit.edu cu Subject: help n antetul mesajului. Regretm c nu
putem rspunde personal la toate mesajele.

Mulumiri
Mai muli prieteni i colegi au contribuit la calitatea acestei cri. Le mulumim tuturor
pentru ajutorul dat i pentru observaiile constructive pe care ni le-au adresat.
Laboratorul de Informatic al Universitii MIT a reprezentat un cadru de lucru ideal. n
mod deosebit, colegii notri de la laboratorul Grupului de Teoria Calculatoarelor ne-au ajutat
i acceptat cererile noastre continue de parcurgere critic a capitolelor. Dorim s mulumim
n mod special urmtorilor colegi: Baruch Awerbuch, Shafi Goldwasser, Leo Guibas, Tom
Leighton, Albert Meyer, David Shmoys i Eva Tardos. Mulumiri lui William Ang, Sally Bemus,
Ray Hirschfeld i Mark Reinhold pentru ntreinerea calculatoarelor (DEC Microvax, Apple
Macintosh i Sun Sparcstation) i pentru recompilarea TEX ori de cte ori am depit limita
timpului de compilare. Menionm ajutorul oferit lui Charles Leiserson de Machines Corporation,
pentru a putea lucra la aceast carte chiar i n perioada absenei sale de la MIT.
Muli dintre colegii notri au folosit manuscrise ale acestei cri pentru cursuri predate la alte
coli, sugernd numeroase corecii i revizuiri. Dorim s mulumim n mod deosebit urmtorilor:
Richard Beigel (Yale), Andrew Goldberg (Stanford), Joan Lucas (Rutgers), Mark Overmars
(Utrecht), Alan Sherman (Tufts i Maryland) i Diane Souvaine (Rutgers).
De asemenea, muli asisteni ai cursurilor noastre au avut contribuii majore la dezvoltarea
acestei cri. Mulumim n mod special urmtorilor: Alan Baratz, Bonnie Berger, Aditi Dhagat,
Burt Kaliski, Arthur Lent, Andrew Moulton, Marios Papaefthymiou, Cindy Phillips, Mark
Reinhold, Phil Rogaway, Flavio Rose, Arie Rudich, Alan Sherman, Cliff Stein, Susmita Sur,
Gregory Troxel i Margaret Tuttle.
Asistena tehnic necesar a fost asigurat de mai multe persoane. Denise Sergent a petrecut
multe ore n bibliotecile universitii MIT pentru a cuta referine bibliografice. Maria Sensale,
bibliotecara slii noastre de lectur, a fost tot timpul deosebit de sritoare. Accesul la biblioteca
personal a lui Albert Meyer ne-a economisit mult timp n pregtirea referinelor bibliografice.
Shlomo Kipnis, Bill Niehaus i David Wilson au demonstrat vechi exerciii, au propus unele noi i
au schiat notie relative la rezolvarea lor. Marios Papaefthymiou i Gregory Troxel au contribuit
la realizarea indexului. De-a lungul anilor, secretarele nostre: Inna Radzihovsky, Denise Sergent,
Gayle Sherman i n mod deosebit Be Hubbard au fost un sprijin continuu n acest proiect,
pentru care le aducem mulumiri.
Multe erori din primele manuscrise au fost detectate de studeni. Mulumim n mod special
urmtorilor: Bobby Blumofe, Bonnie Eisenberg, Raymond Johnson, John Keen, Richard Lethin,
Mark Lillibridge, John Pezaris, Steve Ponzio i Margaret Tuttle pentru parcurgerile i corecturile
efectuate.
De asemenea, colegii notri au adus critici asupra anumitor capitole, ne-au oferit indicaii
asupra unor algoritmi specifici, motiv pentru care le suntem ndatorai. Mulumim n mod
xiv Prefa

deosebit urmtorilor: Bill Aiello, Alok Aggarwal, Eric Bach, Vaek Chvtal, Richard Cole, Johan
Hastad, Alex Ishii, David Johnson, Joe Killian, Dina Kravets, Bruce Maggs, Jim Orlin, James
Park, Thane Plambeck, Hershel Safer, Jeff Shallit, Cliff Stein, Gil Strang, Bob Tarjan i Paul
Wang. Civa colegi ne-au oferit probleme propuse; le mulumim urmtorilor: Andrew Goldberg,
Danny Sleator i Umesh Vazirani.
Aceast carte a fost redactat cu LATEX, un pachet de macrouri TEX. Figurile au fost desenate
pe Apple Macintosh folosind MacDraw II; mulumim lui Joanna Terry de la Claris Corporation
i lui Michael Mahoney de la Advanced Computer Graphics pentru sprijinul lor. Indexul a
fost compilat folosind Windex, un program C scris de autori. Bibliografia a fost pregtit
folosind BibTEX. Cartea a fost tiprit la American Mathematical Society cu ajutorul unei
maini Autologic; mulumim lui Ralph Youngen de la AMS pentru ajutorul dat. Coperta crii
a fost conceput de Jeannet Leendertse. Design-ul crii a fost creat de Rebecca Daw, iar Amy
Hendrickson l-a implementat n LATEX.
Colaborarea cu MIT Press i McGraw-Hill a fost deosebit de plcut. Mulumim n mod
special urmtorilor: Frank Satlow, Terry Ehling, Larry Cohen i Lorrie Lejeune de la MIT Press
i David Shapiro de la McGraw-Hill pentru ncurajri, sprijin i rbdare. Suntem deosebit de
recunosctori lui Larry Cohen pentru editarea excepional.
n fine, mulumim soiilor noastre Nicole Cormen, Linda Lue Leiserson i Gail Rivest
i copiilor notri Ricky, William i Debby Leiserson i Alex i Christopher Rivest pentru
dragostea i sprijinul lor pe ntreaga durat a scrierii acestei cri. (Alex Rivest ne-a ajutat n
mod special cu Paradoxul zilei de natere a marianului). Dragostea, rbdarea i ncurajarea
din partea familiilor noastre au fcut acest proiect posibil. Le dedicm din suflet aceast carte lor.

Cambridge, Massachusetts Thomas H. Cormen


Martie, 1990 Charles E. Leiserson
Ronald L. Rivest
1 Introducere

Acest capitol v va familiariza cu conceptele de baz folosite n aceast carte, referitor la


proiectarea i analiza algoritmilor. Este un text, practic, independent de restul crii, dar include
cteva referiri la materialul care va fi introdus n partea I.
ncepem cu o discuie asupra problemelor generale ale calculabilitii i ale algoritmilor
necesari pentru rezolvarea acestora, cu problema sortrii, ca exemplu introductiv. Pentru a
arta cum vom specifica algoritmii prezentai, vom introduce un pseudocod, care ar trebui
s fie familiar cititorilor obinuii cu programarea. Sortarea prin inserie, un algoritm simplu
de sortare, va servi ca exemplu iniial. Vom analiza timpul de execuie pentru sortarea prin
inserie, introducnd o notaie care s descrie modul n care crete acest timp o dat cu numrul
obiectelor aflate n operaia de sortare. De asemenea, vom introduce n proiectarea algoritmilor
metoda divide i stpnete, pe care o vom utiliza pentru dezvoltarea unui algoritm numit sortare
prin interclasare. Vom ncheia cu o comparaie ntre cei doi algoritmi de sortare.

1.1. Algoritmi
Fr a fi foarte exaci, spunem c un algoritm este orice procedur de calcul bine definit
care primete o anumit valoare sau o mulime de valori ca date de intrare i produce o
anumit valoare sau mulime de valori ca date de ieire. Astfel, un algoritm este un ir de pai
care transform datele de intrare n date de ieire.
Putem, de asemenea, s privim un algoritm ca pe un instrument de rezolvare a problemelor
de calcul bine definite. Enunul problemei specific, n termeni generali, relaia dorit
intrare/ieire. Algoritmul descrie o anumit procedur de calcul pentru a se ajunge la aceast
legtur intrare/ieire.
Vom ncepe studiul algoritmilor cu problema sortrii unui ir de numere n ordine nedescres-
ctoare. Aceast problem apare frecvent n practic i furnizeaz o baz foarte util pentru
introducerea multor metode standard pentru proiectarea i analiza algoritmilor. Iat cum vom
defini formal problema sortrii :
Date de intrare: Un ir de n numere ha1 , a2 , . . . , an i.

Date de ieire: O permutare (reordonare) a irului iniial, ha01 , a02 , . . . , a0n i astfel nct a01
a02 a0n .
Fiind dat un ir de intrare, ca, de exemplu, h31, 41, 59, 26, 41, 58i, un algoritm de sortare
returneaz, la ieire, irul h26, 31, 41, 41, 58, 59i. Un ir de intrare ca cel de mai sus se numete
o instan a problemei de sortare. n general, prin instan a unei probleme se va nelege
mulimea tuturor datelor de intrare (care satisface restriciile impuse n definirea problemei)
necesare pentru a determina o soluie a problemei.
Sortarea este o operaie fundamental n informatic (multe programe o folosesc ca pas
intermediar) i, ca urmare, a fost dezvoltat un numr mare de algoritmi de sortare. Care algoritm
este cel mai bun pentru o aplicaie dat depinde de numrul de obiecte care trebuie sortate, de
2 Capitolul 1 Introducere

Figura 1.1 Modul de sortare a unei mini de cri, utiliznd sortarea prin inserie.

gradul n care aceste obiecte sunt deja sortate ntr-un anumit fel i de tipul de mediu electronic
care urmeaz s fie folosit: memorie principal, discuri sau benzi magnetice.
Un algoritm este corect dac, pentru orice instan a sa, se termin furniznd ieirea corect.
Vom spune c un algoritm corect rezolv problema de calcul dat. Un algoritm incorect s-ar
putea s nu se termine deloc n cazul unor anumite instane de intrare, sau s-ar putea termina
producnd un alt rspuns dect cel dorit. Contrar a ceea ce s-ar putea crede, algoritmii incoreci
pot fi uneori utili dac rata lor de eroare poate fi controlat. Vom vedea un exemplu n capitolul
33, cnd vom studia algoritmi pentru gsirea numerelor prime foarte mari. Totui, n general ne
vom ocupa doar de algoritmi coreci.
Concret, un algoritm poate fi specificat printr-un program pentru calculator sau chiar ca un
echipament hardware. Singura condiie este aceea ca specificaiile s produc o descriere precis
a procedurii de calcul care urmeaz a fi parcurs.
n aceast carte vom descrie algoritmii sub forma unor programe scrise ntr-un pseudocod
care seamn foarte mult cu limbajele C, Pascal sau Algol. Dac suntei ct de ct familiarizai
cu oricare dintre acestea, nu vei avea probleme n a citi algoritmii notri. Ceea ce difereniaz
codul real de pseudocod este faptul c vom folosi metoda cea mai clar i mai concis pentru a
descrie un algoritm dat. O alt diferen dintre pseudocod i codul real este aceea c pseudocodul
nu se ocup de detalii de utilizare. Problemele abstractizrii datelor, a modularitii sau a tratrii
erorilor sunt deseori ignorate, pentru a transmite ct mai concis esena algoritmului.

Sortarea prin inserie


ncepem cu sortarea prin inserie, care este un algoritm eficient pentru sortarea unui
numr mic de obiecte. Sortarea prin inserie funcioneaz n acelai fel n care muli oameni
sorteaz un pachet de cri de joc obinuite. Se ncepe cu pachetul aezat pe mas cu faa n jos
i cu mna stng goal. Apoi, lum cte o carte de pe mas i o inserm n poziia corect n
mna stng. Pentru a gsi poziia corect pentru o carte dat, o comparm cu fiecare dintre
crile aflate deja n mna stng, de la dreapta la stnga, aa cum este ilustrat n figura 1.1.
1.1. Algoritmi 3

Pseudocodul pentru sortarea prin inserie este prezentat ca o procedur numit Sorteaz-
Prin-Inserie, care are ca parametru un vector A[1..n] coninnd un ir de lungime n care
urmeaz a fi sortat. (Pe parcursul codului, numrul de elemente ale lui A este notat prin
lungime[A].) Numerele de intrare sunt sortate pe loc, n cadrul aceluiai vector A; cel mult
un numr constant dintre acestea sunt memorate n zone de memorie suplimentare. Cnd
Sorteaz-Prin-Inserie se termin, vectorul iniial A va conine elementele irului de ieire
sortat.
Sorteaz-Prin-Inserie(A)
1: pentru j 2, lungime[A] execut
2: cheie A[j]
3: Insereaz A[j] n irul sortat A[1..j 1]
4: ij1
5: ct timp i > 0 i A[i] > cheie execut
6: A[i + 1] A[i]
7: ii1
8: A[i + 1] cheie

Figura 1.2 ilustreaz modul de funcionare a acestui algoritm pentru A = h5, 2, 4, 6, 1, 3i.
Indicele j corespunde crii care urmeaz a fi inserat n mna stng. Elementele A[1..j
1] corespund mulimii de cri din mn, deja sortate, iar elementele A[j + 1..n] corespund
pachetului de cri aflate nc pe mas. Indicele se deplaseaz de la stnga la dreapta n interiorul
vectorului. La fiecare iteraie, elementul A[j] este ales din vector (linia 2). Apoi, plecnd de la
poziia j 1, elementele sunt, succesiv, deplasate o poziie spre dreapta pn cnd este gsit
poziia corect pentru A[j] (liniile 47), moment n care acesta este inserat (linia 8).

Convenii pentru pseudocod


La scrierea pseudocodului vom folosi urmtoarele convenii:

1. Indentarea indic o structur de bloc. De exemplu, corpul ciclului pentru, care ncepe n
linia 1, const din liniile 28 iar corpul ciclului ct timp, care ncepe n linia 5, conine
liniile 67, dar nu i linia 8. Stilul nostru de indentare se aplic i structurilor de tipul
dac-atunci-altfel. Folosirea indentrii n locul unor indicatori de bloc de tipul begin i
end, reduce cu mult riscul de confuzie, mbuntind claritatea prezentrii.1

2. Ciclurile de tipul ct timp, pentru, repet i construciile condiionale dac, atunci i


altfel au aceeai interpretare ca i structurile similare din Pascal.

3. Simbolul indic faptul c restul liniei este un comentariu.

4. O atribuire multipl de forma i j e nseamn atribuirea valorii expresiei e ambelor


variabile i i j; aceasta ar trebui tratat ca un echivalent al atribuirii j e, urmat de
atribuirea i j.
1 n limbajele de programare reale, indentarea, ca unic metod pentru indicarea structurilor de bloc, nu este

n general recomandabil, deoarece nivelurile de indentare se determin greoi n cazul unor coduri care se continu
pe mai multe pagini.
4 Capitolul 1 Introducere

Figura 1.2 Modul de operare a procedurii Sorteaz-Prin-Inserie asupra vectorului A =


h5, 2, 4, 6, 1, 3i. Poziia indicelui j este indicat printr-un cerc.

5. Variabilele (de exemplu i, j, cheie) sunt locale pentru o procedur dat. Nu vom utiliza
variabile globale fr a preciza acest lucru n mod explicit.

6. Elementele unui vector sunt accesate specificnd numele vectorului urmat de indice n
paranteze drepte. De exemplu, A[i] indic elementul de rang i al vectorului A. Notaia ..
este folosit pentru a indica un domeniu de valori n cadrul unui vector. Astfel, A[1..j]
indic un subvector al lui A constnd din elementele A[1], A[2], . . . , A[j].

7. Datele compuse sunt, n mod uzual, organizate n obiecte care conin atribute sau cm-
puri . Un anumit cmp este accesat folosind numele cmpului urmat de numele obiectului
su n paranteze drepte. De exemplu, tratm un vector ca pe un obiect cu atributul lungime
indicnd numrul de elemente ale acestuia. Pentru a specifica numrul de elemente ale unui
vector A, se va scrie lungime[A]. Dei vom folosi parantezele drepte att pentru indexarea
elementelor unui vector, ct i pentru atributele obiectelor, va fi clar din context care este
interpretarea corect.
O variabil reprezentnd un vector sau un obiect este tratat ca un pointer spre datele
care reprezint vectorul sau obiectul. Pentru toate cmpurile f ale unui obiect x, atribuirea
y x are ca efect f [y] = f [x]. Mai mult, dac acum avem f [x] 3, atunci nu numai
f [x] = 3, dar, n acelai timp, avem si f [y] = 3. Cu alte cuvinte, x i y indic spre (sau
sunt) acelai obiect dup atribuirea y x. Uneori, un pointer nu se va referi la nici un
obiect. n acest caz special pointerul va primi valoarea nil.

8. Parametrii sunt transmii unei proceduri prin valoare: procedura apelat primete pro-
pria sa copie a parametrilor i, dac atribuie o valoare unui parametru, schimbarea nu este
vzut de procedura apelant. Cnd obiectele sunt transmise procedurii, este copiat doar
pointerul spre datele reprezentnd obiectul, nu i cmpurile acestuia. De exemplu, dac x
este un parametru al unei proceduri apelate, atribuirea x y n cadrul procedurii apelate
nu este vizibil din procedura apelant. Atribuirea f [x] 3 este, totui, vizibil.
1.2. Analiza algoritmilor 5

Exerciii
1.1-1 Folosind ca model figura 1.2, ilustrai modul de operare al procedurii Sorteaz-Prin-
Inserie asupra vectorului A = h31, 41, 59, 26, 41, 58i.

1.1-2 Rescriei procedura Sorteaz-Prin-Inserie pentru a sorta n ordine necresctoare n


loc de ordine nedescresctoare.

1.1-3 S considerm problema cutrii :


Date de intrare: Un ir de n numere A = ha1 , a2 , . . . , an i i o valoare v.
Date de ieire: Un indice i astfel nct v = A[i] sau valoarea special nil dac v nu apare n
A.
Scriei un algoritm pentru o cutare liniar, care parcurge irul n cutarea lui v.

1.1-4 S considerm problema adunrii a doi ntregi binari pe n bii memorai n doi vectori
n-dimensionali A i B. Suma celor doi ntregi trebuie s fie memorat n form binar ntr-un
vector C avnd n + 1 elemente. Gsii un enun formal al problemei i scriei un algoritm pentru
adunarea celor doi ntregi.

1.2. Analiza algoritmilor


Analiza unui algoritm a ajuns s nsemne prevederea resurselor pe care algoritmul le solicit.
Uneori, resurse ca memoria, limea benzii de comunicaie, pori logice sunt prima preocupare,
dar, de cele mai multe ori, vrem s msurm timpul de execuie necesar algoritmului. n general,
analiznd mai muli algoritmi pentru o anumit problem, cel mai eficient poate fi identificat
uor. O astfel de analiz poate indica mai muli candidai viabili, dar civa algoritmi inferiori
sunt, de obicei, eliminai n timpul analizei.
nainte de a analiza un algoritm, trebuie s avem un model al tehnologiei de implementare care
urmeaz s fie folosit, incluznd un model pentru resursele acesteia i costurile corespunztoare.
n cea mai mare parte a acestei cri, vom presupune c tehnologia de implementare este un
model de calcul generic cu un procesor, main cu acces aleator (random-access machine,
RAM) i vom presupune c algoritmii vor fi implementai ca programe pentru calculator. n
modelul RAM, instruciunile sunt executate una dup alta, fr operaii concurente. Totui, n
partea final a crii, vom avea ocazia s investigm modele de calcul paralel i hardware digital.
Analiza, chiar i a unui singur algoritm, poate fi, uneori, o ncercare dificil. Matematica
necesar poate s includ combinatoric, teoria probabilitilor, dexteritate algebric i abilitatea
de a identifica cei mai importani termeni ntr-o expresie. Deoarece comportarea unui algoritm
poate fi diferit n funcie de datele de intrare, avem nevoie de un mijloc de exprimare a acestei
comportri n formule simple, uor de neles.
Dei, pentru a analiza un algoritm, selectm numai un anumit tip de model de main de
calcul, rmn mai multe posibiliti de alegere a felului n care decidem s exprimm aceast
analiz. Un scop imediat este de a gsi un mijloc de exprimare care s fie simplu de scris i de
manevrat, care s arate principalele resurse necesare unui algoritm i s suprime detaliile inutile.
6 Capitolul 1 Introducere

Analiza sortrii prin inserie


Timpul de execuie necesar procedurii Sorteaz-Prin-Inserie depinde de intrare: sortarea
a o mie de numere ia mai mult timp dect sortarea a trei. Mai mult dect att, Sorteaz-
Prin-Inserie poate s consume timpi diferii pentru a sorta dou iruri de numere de aceeai
dimensiune, n funcie de msura n care acestea conin numere aproape sortate. n general,
timpul necesar unui algoritm crete o dat cu dimensiunea datelor de intrare, astfel nct este
tradiional s se descrie timpul de execuie al unui program n funcie de dimensiunea datelor de
intrare. n acest scop, trebuie s definim cu mai mult precizie termenii de timp de execuie i
dimensiune a datelor de intrare.
Definiia dimensiunii datelor de intrare depinde de problema studiat. Pentru multe
probleme, cum ar fi sortarea sau calculul unei transformate Fourier discrete, cea mai natural
msur este numrul de obiecte din datele de intrare de exemplu, pentru sortare, un vector
de dimensiune n. Pentru multe alte probleme, ca spre exemplu nmulirea a doi ntregi, cea
mai bun msur pentru dimensiunea datelor de intrare este numrul total de bii necesari
pentru reprezentarea datelor de intrare n notaie binar. Uneori, este mai potrivit s exprimm
dimensiunea datelor de intrare prin dou numere n loc de unul. De exemplu, dac datele de
intrare ale unui algoritm sunt reprezentate de un graf, dimensiunea datelor de intrare poate fi
descris prin numrul de vrfuri i muchii ale grafului. Pentru fiecare problem pe care o vom
studia, vom indica msura utilizat pentru dimensiunea datelor de intrare.
Timpul de execuie a unui algoritm pentru un anumit set de date de intrare este determinat
de numrul de operaii primitive sau pai executai. Este util s definim noiunea de pas astfel
nct s fie ct mai independent de calculator. Pentru moment, s adoptm urmtorul punct de
vedere. Pentru execuia unei linii din pseudocod este necesar o durat constant de timp. O
anumit linie poate avea nevoie de un timp de execuie diferit dect o alta, dar vom presupune c
fiecare execuie a liniei i consum timpul ci , unde ci este o constant. Acest punct de vedere este
conform cu modelul RAM i, n acelai timp, reflect, destul de bine, modul n care pseudocodul
poate fi, de fapt, utilizat n cele mai multe cazuri concrete.2
n prezentarea care urmeaz, expresia noastr pentru timpul de execuie al algoritmului
Sorteaz-Prin-Inserie va evolua de la o formul relativ complicat, care folosete toate
costurile de timp ci , la una mult mai simpl n notaii, care este mai concis i mai uor de
manevrat. Aceast notaie mai simpl va face, de asemenea, uor de determinat dac un algoritm
este mai eficient dect altul.

ncepem prin a relua prezentarea procedurii Sorteaz-Prin-Inserie, adugnd costul


de timp pentru fiecare instruciune i un numr care reprezint de cte ori aceasta este efectiv
executat. Pentru fiecare j = 2, 3, . . . , n, unde n = lungime[A], vom nota cu tj numrul de
execuii ale testului ct timp din linia 5 pentru valoarea fixat j. Vom presupune c un
comentariu nu este o instruciune executabil, prin urmare nu cere timp de calcul.
Timpul de execuie al algoritmului este suma tuturor timpilor de execuie corespunztori
2 Exist aici cteva subtiliti: paii de calcul pe care i precizm sunt, cel mai adesea, variante ale unor

proceduri care cer mai mult dect doar un timp constant. De exemplu, n continuare, n aceast carte am putea
spune, ntr-o linie de pseudocod, sorteaz punctele conform coordonatei x, care, aa cum vom vedea, cere mai
mult dect un timp constant. De asemenea, se poate observa c o instruciune care apeleaz o subrutin are
nevoie de un timp constant, dei subrutina, o dat apelat, are nevoie de mai mult timp de execuie. Din acest
motiv, separm procesul de a apela o subrutin trecerea parametrilor ctre aceasta etc. de procesul de a
executa subrutina.
1.2. Analiza algoritmilor 7

Sorteaz-Prin-Inserie(A) cost timp


1: pentru j 2, lungime[A] execut c1 n
2: cheie A[j] c2 n1
3: Insereaz A[j] n irul sortat A[1..j 1] 0 n1
4: ij1 c4 n
P 1 n
5: ct timp i > 0 i A[i] > cheie execut c5 t
Pnj=2 j
6: A[i + 1] A[i] c6 (t j 1)
Pj=2
n
7: ii1 c7 j=2 j 1)
(t
8: A[i + 1] cheie c8 n1

fiecrei instruciuni executate: o instruciune care consum timpul ci pentru execuie i este
executat de n ori, va contribui cu ci n la timpul total de execuie.3 Pentru a calcula T (n),
timpul de execuie pentru Sorteaz-Prin-Inserie, vom aduna produsele mrimilor indicate
n coloanele cost i timp, obinnd
n
X n
X n
X
T (n) = c1 n + c2 (n 1) + c4 (n 1) + c5 tj + c6 (tj 1) + c7 (tj 1)
j=2 j=2 j=2
+ c8 (n 1).

Chiar pentru date de intrare de aceeai mrime, timpul de execuie al unui algoritm dat poate
s depind de coninutul datelor de intrare. De exemplu, pentru Sorteaz-Prin-Inserie, cazul
cel mai favorabil apare cnd vectorul de intrare este deja sortat. Pentru fiecare j = 2, 3 . . . , n,
vom gsi c A[i] cheie n linia 5, cnd i are valoarea iniial j 1. Rezult tj = 1 pentru
j = 2, 3, . . . , n i timpul de execuie n cazul cel mai favorabil este

T (n) = c1 n + c2 (n 1) + c4 (n 1) + c5 (n 1) + c8 (n 1)
= (c1 + c2 + c4 + c5 + c8 )n (c2 + c4 + c5 + c8 ).

Acest timp de execuie poate fi exprimat sub forma an + b pentru anumite constante a i b care
depind doar de timpii de execuie ci , fiind astfel o funcie liniar de n.
Dac vectorul este sortat n ordine invers adic, n ordine descresctoare obinem cazul
cel mai defavorabil. n aceast situaie trebuie s comparm fiecare element A[j] cu fiecare
element din subvectorul A[1..j 1], i, astfel, tj = j pentru j = 2, 3, . . . , n. Observnd c
n
X n(n + 1)
j= 1
j=2
2

i
n
X n(n 1)
(j 1) =
j=2
2

3 Un fenomen de acest tip nu mai are loc atunci cnd se refer la alte resurse, cum ar fi, de exemplu, memoria.

O instruciune care se refer la m cuvinte din memorie i este executat de n ori, nu consum n general mn
cuvinte de memorie.
8 Capitolul 1 Introducere

(vom reveni asupra acestor sume n capitolul 3), gsim c n cazul cel mai defavorabil timpul de
execuie pentru Sorteaz-Prin-Inserie este

n(n + 1) n(n 1)
T (n) = c1 n + c2 (n 1) + c4 (n 1) + c5 1 + c6
2 2

n(n 1)
+ c7 + c8 (n 1)
2
c c6 c7 c5 c6 c7
5
= + + n2 + c1 + c2 + c4 + + c8 n
2 2 2 2 2 2
(c2 + c4 + c5 + c8 ) .

Rezult c timpul de execuie n cazul cel mai defavorabil poate fi exprimat sub forma
an2 + bn + c, unde constantele a, b i c depind, din nou, de costurile ci ale instruciunilor, fiind
astfel o funcie ptratic de n.
De obicei, la fel ca la sortarea prin inserie, timpul de execuie al unui algoritm dat este
fix pentru anumite date de intrare. Totui, n ultimele capitole, vom ntlni civa algoritmi
aleatori a cror comportare poate varia chiar pentru aceleai date de intrare.

Analiza celui mai defavorabil caz i a cazului mediu


n analiza sortrii prin inserie am cercetat ambele situaii extreme: cazul cel mai favorabil, n
care vectorul de intrare era deja sortat, respectiv cel mai defavorabil, n care vectorul de intrare
era sortat n ordine invers. n continuare (pe tot parcursul acestei cri), ne vom concentra, de
regul, pe gsirea timpului de execuie n cazul cel mai defavorabil , cu alte cuvinte, a
celui mai mare timp de execuie posibil relativ la orice date de intrare de dimensiune constant
n. Precizm trei motive pentru aceast orientare:

Timpul de execuie al unui algoritm n cazul cel mai defavorabil este o margine superioar
a timpului de execuie pentru orice date de intrare de dimensiune fix. Cunoscnd acest
timp, avem o garanie c algoritmul nu va avea, niciodat, un timp de execuie mai mare.
Nu va fi nevoie s facem presupuneri sau investigaii suplimentare asupra timpului de
execuie i s sperm c acesta nu va fi, niciodat, mult mai mare.

Pentru anumii algoritmi, cazul cel mai defavorabil apare destul de frecvent. De exemplu,
n cutarea unei anumite informaii ntr-o baz de date, cazul cel mai defavorabil al
algoritmului de cutare va apare deseori cnd informaia cutat nu este de fapt prezent
n baza de date. n anumite aplicaii, cutarea unor informaii absente poate fi frecvent.

Cazul mediu este, adesea, aproape la fel de defavorabil ca i cazul cel mai defavorabil. S
presupunem c alegem la ntmplare n numere i aplicm sortarea prin inserie. Ct timp
va fi necesar pentru a determina locul n care putem insera A[j] n subvectorul A[1..j 1]?
n medie, jumtate din elementele subvectorului A[1..j 1] sunt mai mici dect A[j], i
cealalt jumtate sunt mai mari. Prin urmare, n medie, trebuie verificate jumtate din
elementele subvectorului A[1..j 1], deci tj = j/2. Dac inem seama de aceast observaie,
timpul de execuie mediu va aprea tot ca o funcie ptratic de n, la fel ca n cazul cel
mai defavorabil.
1.2. Analiza algoritmilor 9

n anumite cazuri particulare, vom fi interesai de timpul mediu de execuie al unui


algoritm. O problem care apare n analiza cazului mediu este aceea c s-ar putea s nu fie
prea clar din ce sunt constituite datele de intrare medii pentru o anumit problem. Adesea,
vom presupune c toate datele de intrare avnd o dimensiune dat sunt la fel de probabile. n
practic, aceast presupunere poate fi fals, dar un algoritm aleator poate, uneori, s o foreze.

Ordinul de cretere
Pentru a uura analiza procedurii Sorteaz-Prin-Inserie, am utilizat mai multe presu-
puneri simplificatoare. n primul rnd, am ignorat costul real al fiecrei instruciuni, folosind
constantele ci pentru a reprezenta aceste costuri. Apoi, am observat c, prin aceste constante,
obinem mai multe detalii dect avem nevoie n mod real: timpul de execuie n cazul cel mai
defavorabil este de forma an2 +bn+c pentru anumite constante a, b i c care depind de costurile ci
ale instruciunilor. Astfel, am ignorat nu numai costurile reale ale instruciunilor, dar i costurile
abstracte ci .
Vom face acum nc o abstractizare simplificatoare. Ceea ce ne intereseaz de fapt, este rata
de cretere sau ordinul de cretere a timpului de execuie. Considerm, prin urmare, doar
termenul dominant al formulei (adic an2 ) deoarece ceilali termeni sunt relativ nesemnificativi
pentru valori mari ale lui n. Ignorm, de asemenea, i factorul constant c, deoarece, pentru
numere foarte mari, factorii constani sunt mai puin semnificativi dect rata de cretere n
determinarea eficienei computaionale a unor algoritmi. Astfel, vom spune, de exemplu, c
sortarea prin inserie are un timp de execuie n cazul cel mai defavorabil de (n2 ) (pronunat
teta de n ptrat). Vom folosi notaia de tip n acest capitol cu caracter informal; va fi definit
cu precizie n capitolul 2.
n mod uzual, vom considera un algoritm ca fiind mai eficient dect altul dac timpul su
de execuie n cazul cel mai defavorabil are un ordin de cretere mai mic. Aceast evaluare ar
putea fi incorect pentru date de intrare de dimensiune mic, dar n cazul unor date de intrare
de dimensiuni foarte mari, un algoritm de tipul (n2 ), de exemplu, va fi executat n cazul cel
mai defavorabil mult mai repede dect unul de tipul (n3 ).

Exerciii
1.2-1 S considerm sortarea a n numere memorate ntr-un vector A, pentru nceput gsind
cel mai mic element al lui A i punndu-l ca prim element ntr-un alt vector B. Apoi, gsim al
doilea element mai mic din A i l punem pe poziia a doua a lui B. Continuai n acelai mod
pentru toate elementele lui A. Scriei un pseudocod pentru acest algoritm, care este cunoscut
sub numele de sortarea prin selecie. Gsii timpii de execuie n cazul cel mai favorabil,
respectiv cel mai defavorabil, pentru sortarea prin selecie, utiliznd notaia .

1.2-2 S considerm, din nou, cutarea liniar (vezi exerciiul 1.1-3). Ct de multe elemente ale
irului de intrare trebuie verificate, n medie, presupunnd c elementul cutat se afl printre
termenii irului dat? Ce putei spune despre cazul cel mai defavorabil? Care sunt timpul mediu
de execuie i timpul de execuie n cazul cel mai defavorabil pentru cutarea liniar, exprimai
n notaia ? Justificai rspunsurile.

1.2-3 S considerm problema evalurii unui polinomPntr-un punct. Fiind dai n coeficieni
n1
a0 , a1 , . . . , an1 i un numr real x, dorim s calculm i=0 ai xi . Descriei un algoritm simplu
10 Capitolul 1 Introducere

n timp (n2 ) pentru aceast operaie. Descriei i un algoritm n timp (n) care folosete
urmtoarea metod de rescriere a unui polinom, numit schema lui Horner:
n1
X
ai xi = ( (an1 x + an2 )x + + a1 )x + a0
i=0

1.2-4 Scriei funcia n3 /1000 100n2 100n + 3 cu ajutorul notaiei .

1.2-5 Cum poate fi modificat aproape orice algoritm pentru a avea un timp de execuie bun n
cel mai favorabil caz?

1.3. Proiectarea algoritmilor


Exist multe moduri de proiectare a algoritmilor. Sortarea prin inserie folosete o metod
care s-ar putea numi incremental: avnd deja sortat subvectorul A[1..j 1], inserm elementul
A[j] n locul potrivit producnd subvectorul A[1..j].
n aceast seciune vom examina o abordare diferit, numit divide i stpnete. Vom utiliza
aceast abordare pentru a construi un algoritm de sortare al crui timp de execuie n cazul cel
mai defavorabil va fi mult mai mic dect al celui corespunztor sortrii prin inserie. Unul din
avantajele algoritmilor de tipul divide i stpnete este acela c timpul lor de execuie este
adesea uor de determinat folosind tehnici care vor fi introduse n capitolul 4.

1.3.1. Abordarea divide i stpnete


Muli algoritmi utili au o structur recursiv: pentru a rezolva o problem dat, acetia sunt
apelai de ctre ei nii o dat sau de mai multe ori pentru a rezolva subprobleme apropiate.
Aceti algoritmi folosesc de obicei o abordare de tipul divide i stpnete: ei rup problema
de rezolvat n mai multe probleme similare problemei iniiale, dar de dimensiune mai mic, le
rezolv n mod recursiv i apoi le combin pentru a crea o soluie a problemei iniiale.
Paradigma divide i stpnete implic trei pai la fiecare nivel de recursivitate:
Divide problema ntr-un numr de subprobleme.
Stpnete subproblemele prin rezolvarea acestora n mod recursiv. Dac dimensiunile acestora
sunt suficient de mici, rezolv subproblemele n modul uzual, nerecursiv.
Combin soluiile tuturor subproblemelor n soluia final pentru problema iniial.
Algoritmul de sortare prin interclasare urmeaz ndeaproape paradigma divide i stp-
nete. Intuitiv, acesta opereaz astfel.
Divide: mparte irul de n elemente care urmeaz a fi sortat n dou subiruri de cte n/2
elemente.
Stpnete: Sorteaz recursiv cele dou subiruri utiliznd sortarea prin interclasare.
Combin: Interclaseaz cele dou subiruri sortate pentru a produce rezultatul final.
1.3. Proiectarea algoritmilor 11

Figura 1.3 Modul de operare al sortrii prin interclasare asupra vectorului A = h5, 2, 4, 6, 1, 3, 2, 6i.
Lungimile irurilor sortate, n curs de interclasare, cresc pe msur ce algoritmul avanseaz de jos n sus.

S observm c recursivitatea se oprete cnd irul de sortat are lungimea 1, caz n care nu mai
avem nimic de fcut, deoarece orice ir de lungime 1 este deja sortat.
Operaia principal a algoritmului de sortare prin interclasare este interclasarea a dou iruri
sortate, n pasul denumit mai sus Combin. Pentru aceasta vom utiliza o procedur auxiliar,
Interclaseaz(A, p, q, r), unde A este un vector i p, q i r sunt indici ai vectorului, astfel
nct p q < r. Procedura presupune c subvectorii A[p..q] i A[q + 1..r] sunt sortai. Ea i
interclaseaz pentru a forma un subvector sortat care nlocuiete subvectorul curent A[p..r].
Dei vom lsa pseudocodul pentru aceast procedur ca exerciiu (vezi exerciiul 1.3-2), este
uor de imaginat o procedur de tip Interclaseaz al crei timp de execuie este de ordinul
(n), n care n = r p + 1 este numrul elementelor interclasate. Revenind la exemplul nostru
cu crile de joc, s presupunem c avem dou pachete de cri de joc aezate pe mas cu faa
n sus. Fiecare din cele dou pachete este sortat, cartea cu valoarea cea mai mic fiind deasupra.
Dorim s amestecm cele dou pachete ntr-un singur pachet sortat, care s rmn aezat pe
mas cu faa n jos. Pasul principal este acela de a selecta cartea cu valoarea cea mai mic dintre
cele dou aflate deasupra pachetelor (fapt care va face ca o nou carte s fie deasupra pachetului
respectiv) i de a o pune cu faa n jos pe locul n care se va forma pachetul sortat final. Repetm
acest procedeu pn cnd unul din pachete este epuizat. n aceast faz, este suficient s lum
pachetul rmas i s-l punem peste pachetul deja sortat ntorcnd toate crile cu faa n jos.
Din punctul de vedere al timpului de execuie, fiecare pas de baz dureaz un timp constant,
deoarece comparm de fiecare dat doar dou cri. Deoarece avem de fcut cel mult n astfel de
operaii elementare, timpul de execuie pentru procedura Interclaseaz este (n).

Acum, putem utiliza procedura Interclaseaz ca subrutin pentru algoritmul de sortare


12 Capitolul 1 Introducere

Sorteaz-Prin-Interclasare(A, p, r)
1: dac p < r atunci
2: q b(p + r)/2c
3: Sorteaz-Prin-Interclasare(A, p, q)
4: Sorteaz-Prin-Interclasare(A, q + 1, r)
5: Interclaseaz(A, p, q, r)

prin interclasare. Procedura Sorteaz-Prin-Interclasare(A, p, r) sorteaz elementele din


subvectorul A[p..r]. Dac p r, subvectorul are cel mult un element i este, prin urmare, deja
sortat. Altfel, pasul de divizare este prezent aici prin simplul calcul al unui indice q care m-
parte A[p..r] n doi subvectori, A[p..q] coninnd dn/2e elemente i A[q + 1..r] coninnd bn/2c
elemente.4 Pentru a sorta ntregul ir A = hA[1], A[2], . . . A[n]i, vom apela procedura Sortea-
z-Prin-Interclasare sub forma Sorteaz-Prin-Interclasare(A, 1, lungime[A]) unde, din
nou, lungime[A] = n. Dac analizm modul de operare al procedurii, de jos n sus, cnd n este
o putere a lui 2, algoritmul const din interclasarea perechilor de iruri de lungime 1, pentru a
forma iruri sortate de lungime 2, interclasarea acestora n iruri sortate de lungime 4, i aa
mai departe, pn cnd dou iruri sortate de lungime n/2 sunt interclasate pentru a forma irul
sortat final de dimensiune n. Figura 1.3 ilustreaz acest proces.

1.3.2. Analiza algoritmilor de tipul divide i stpnete


Cnd un algoritm conine un apel recursiv la el nsui, timpul su de execuie poate fi, adesea,
descris printr-o relaie de recuren sau, mai simplu, recuren, care descrie ntregul timp
de execuie al unei probleme de dimensiune n cu ajutorul timpilor de execuie pentru date de
intrare de dimensiuni mai mici. Putem, apoi, folosi instrumente matematice pentru a rezolva
problema de recuren i pentru a obine margini ale performanei algoritmului.
O recuren pentru timpul de execuie al unui algoritm de tipul divide-et-impera se bazeaz
pe cele trei etape definite n descrierea metodei. La fel ca pn acum, vom nota cu T (n) timpul
de execuie al unei probleme de mrime n. Dac dimensiunea problemei este suficient de mic,
de exemplu n c pentru o anumit constant c, soluia direct ia un timp constant de execuie,
pe care l vom nota cu (1). S presupunem c divizm problema n a subprobleme, fiecare
dintre acestea avnd dimensiunea de 1/b din dimensiunea problemei originale. Dac D(n) este
timpul necesar pentru a divide problema n subprobleme, iar C(n) este timpul necesar pentru a
combina soluiile subproblemelor n soluia problemei originale, obinem recurena

(1) dac n c,
T (n) =
aT (n/b) + D(n) + C(n) n caz contrar.

n capitolul 4 vom vedea cum se pot rezolva recurene uzuale pentru probleme de aceast
form.

Analiza sortrii prin interclasare


Dei algoritmul Sorteaz-Prin-Interclasare funcioneaz corect cnd numrul elemen-
telor nu este par, analiza bazat pe recuren se simplific dac presupunem c dimensiunea
4 Notaia dxe desemneaz cel mai mic numr ntreg mai mare sau egal dect x i bxc desemneaz cel mai mare

numr ntreg mai mic sau egal dect x. Aceste notaii sunt definite n capitolul 2.
1.3. Proiectarea algoritmilor 13

problemei originale este o putere a lui 2. Fiecare pas de mprire genereaz deci dou subiruri
avnd dimensiunea exact n/2. n capitolul 4 vom vedea c aceast presupunere nu afecteaz
ordinul de cretere a soluiei recurenei.
Pentru a determina recurena pentru T (n), timpul de execuie al sortrii prin interclasare a
n numere n cazul cel mai defavorabil, vom raiona n felul urmtor. Sortarea prin interclasare a
unui singur element are nevoie de un timp constant. Cnd avem n > 1 elemente, vom descompune
timpul de execuie dup cum urmeaz:
Divide: La acest pas, se calculeaz doar mijlocul subvectorului, calcul care are nevoie de un
timp constant de execuie. Astfel, D(n) = (1).
Stpnete: Rezolvm recursiv dou subprobleme, fiecare de dimensiune n/2, care contribuie
cu 2T (n/2) la timpul de execuie.
Combin: Am observat deja c procedura Interclaseaz pentru un subvector cu n elemente
consum (n) timp de execuie, deci C(n) = (n).
Cnd adunm funciile D(n) i C(n) pentru analiza sortrii prin interclasare, adunm o funcie
cu timpul de execuie (n) cu o funcie cu timpul de execuie (1). Aceast sum este funcie
liniar n raport cu n, adic are timpul de execuie (n). Adugnd aceasta la termenul 2T (n/2)
de la pasul Stpnete, obinem timpul de execuie T (n) n cazul cel mai defavorabil pentru
sortarea prin interclasare:

(1) dac n = 1,
T (n) =
2T (n/2) + (n) dac n > 1.

n capitolul 4, vom arta c T (n) este (n lg n), unde lg n reprezint log2 n. Pentru numere
suficient de mari, sortarea prin interclasare, avnd timpul de execuie (n lg n), este mai per-
formant dect sortarea prin inserie, al crei timp de execuie n cazul cel mai defavorabil este
(n2 ).

Exerciii
1.3-1 Utiliznd ca model figura 1.3, ilustrai modul de operare al sortrii prin interclasare pentru
vectorul A = h3, 41, 52, 26, 38, 57, 9, 49i.

1.3-2 Scriei pseudocodul pentru Interclaseaz(A, p, q, r).

1.3-3 Utilizai inducia matematic pentru a arta c, dac n este o putere a lui 2, soluia
recurenei

2 dac n = 2,
T (n) =
2T (n/2) + n dac n = 2k , k > 1.

este T (n) = n lg n.

1.3-4 Sortarea prin inserie poate fi descris ca procedur recursiv n felul urmtor: pentru a
sorta A[1..n], sortm A[1..n 1] i apoi inserm A[n] n vectorul sortat A[1..n 1]. Scriei o
recuren pentru timpul de execuie a acestei versiuni a sortrii prin inserie.
14 Capitolul 1 Introducere

1.3-5 Relund problema cutrii (vezi exerciiul 1.1-3), observai c, dac irul A este sortat,
se poate ncepe prin a compara v cu valoarea aflat la mijlocul vectorului i se poate elimina
din discuie una din jumti. Cutarea binar este un algoritm care repet acest procedeu,
njumtind de fiecare dat partea irului n care se face cutarea. Scriei un pseudocod fie
iterativ, fie recursiv, pentru cutarea binar. Argumentai c timpul de execuie n cazul cel mai
defavorabil este (lg n).

1.3-6 Observai c blocul ct timp (liniile 57) din procedura Sorteaz-Prin-Inserie


(seciunea 1.1) folosete o cutare liniar pentru a parcurge napoi subvectorul A[1..j 1]. Putem
utiliza n locul acesteia o cutare binar (vezi exerciiul 1.3-5), pentru a mbunti timpul de
execuie total pentru sortarea prin inserie n cazul cel mai defavorabil, la valoarea (n lg n)?

1.3-7 ? Descriei un algoritm al crui timp de execuie s fie (n lg n) i care, pornind de la o


mulime dat S de n numere reale i un alt numr real x, s decid dac printre elementele lui
S exist dou elemente avnd suma x.

1.4. Rezumat
Un algoritm bun este ca un cuit ascuit face exact ceea ce se ateapt s fac, cu un
minimum de efort. A folosi un algoritm nepotrivit pentru a rezolva o problem este ca i cum
s-ar ncerca s se taie o friptur cu o urubelni: n final, s-ar obine, eventual, un produs
digerabil, dar cu un efort considerabil mai mare dect cel necesar, iar rezultatul ar fi, probabil,
mai puin plcut din punct de vedere estetic.
Algoritmii care sunt proiectai s rezolve o aceeai problem pot s difere foarte mult n
eficien. Aceste diferene pot fi cu mult mai semnificative dect diferena dintre un calculator
personal i un supercalculator. De exemplu, s ne imaginm un supercalculator care ruleaz
sortarea prin inserie i un calculator personal care ruleaz sortarea prin interclasare. Fiecare
trebuie s sorteze un vector de un milion de numere. S presupunem c supercalculatorul poate
executa 100 milioane de operaii pe secund, n timp ce calculatorul personal execut doar
un milion de operaii pe secund. Pentru a face ca diferena s fie i mai dramatic, vom
presupune c supercalculatorul utilizeaz pentru sortarea prin inserie un program executabil
realizat n cod main, optimizat de ctre cel mai bun programator, rezultatul fiind c sunt
necesare 2n2 instruciuni la supercalculator pentru a realiza sortarea a n numere. Sortarea prin
interclasare, pe de alt parte, se ruleaz cu un program realizat pentru calculatorul personal,
de ctre un programator de nivel mediu, folosind un limbaj de nivel nalt cu un compilator
ineficient, codului rezultat fiindu-i necesare 50n lg n instruciuni. Pentru a sorta un milion de
numere, supercalculatorul are nevoie de

2 (106 )2 instruciuni
= 20.000 secunde 5, 56 ore,
108 instruciuni/secund
n timp ce pentru calculatorul personal sunt necesare

50 106 lg 106 instruciuni


1.000 secunde 16, 67 minute.
106 instruciuni/secund
Probleme 15

Prin utilizarea unui algoritm al crui timp de execuie are un ordin mai mic de cretere, chiar i
un calculator personal obine rezultatul cerut de 20 de ori mai repede dect supercalculatorul!
Acest exemplu arat c algoritmii, la fel ca i echipamentele hardware sunt o tehnologie.
Performana total a unui sistem de calcul depinde tot att de mult de alegerea algoritmilor
eficieni, ct depinde de alegerea unui hardware rapid. Aa cum are loc o dezvoltare tehnologic
rapid n ceea ce privete alte tehnologii legate de calculatoare, tot astfel se dezvolt i algoritmii.

Exerciii
1.4-1 S presupunem c trebuie s comparm implementrile sortrii prin inserie i sortrii
prin interclasare pe acelai calculator. Pentru date de intrare de dimensiune n, sortarea prin
inserie se execut n 8n2 pai, n timp ce sortarea prin interclasare se execut n 64n lg n pai.
Pentru ce valori ale lui n sortarea prin inserie este mai rapid dect sortarea prin interclasare?
Cum s-ar putea rescrie pseudocodul pentru sortarea prin interclasare cu scopul de a o face chiar
mai rapid pentru date de intrare de dimensiuni mici?

1.4-2 Care este cea mai mic valoare a lui n pentru care un algoritm cu timpul de execuie de
100n2 este mai rapid dect un algoritm cu timpul timpul de execuie de 2n ?

1.4-3 S considerm problema de a determina dac un ir arbitrar de n numere hx1 , x2 , . . . , xn i


conine cel puin doi termeni egali. Artai c acest fapt poate fi realizat n (n lg n), n care
lg n reprezint log2 n.

Probleme
1-1 Comparaia timpilor de execuie
Pentru fiecare funcie f (n) i timp t din urmtorul tabel, determinai cea mai mare valoare a lui
n pentru o problem care poate fi rezolvat n timpul t, presupunnd c algoritmul de rezolvare
a problemei are nevoie de f (n) microsecunde.
1 1 1 1 1 1 1
secund minut or zi lun an secol
lg n

n
n
n lg n
n2
n3
2n
n!

1-2 Sortarea prin inserie pe vectori mici n sortarea prin interclasare


Dei timpul de execuie al algoritmului de sortare prin interclasare n cazul cel mai defavorabil
este (n lg n), iar sortarea prin inserie are un timp de execuie pentru situaii similare de (n2 ),
factorii constani din sortarea prin inserie pot face ca aceasta s fie, totui, mai rapid pentru
valori mici ale lui n. Astfel, are sens s se utilizeze sortarea prin inserie n cadrul sortrii prin
16 Capitolul 1 Introducere

interclasare, dac subproblemele devin suficient de mici. S considerm o modificare a sortrii


prin interclasare n care n/k subvectori de lungine k sunt sortai utiliznd sortarea prin inserie
i apoi interclasai folosind procedura standard de sortare prin interclasare, unde k este o valoare
care urmeaz a fi determinat.

a. Artai c cei n/k subvectori, fiecare de lungime k, pot fi sortai prin inserie cu timp de
execuie (nk) n cazul cel mai defavorabil.

b. Artai c aceti subvectori pot fi sortai prin interclasare cu timp de execuie (n lg(n/k))
n cazul cel mai defavorabil.

c. Fiind dat faptul c algoritmul modificat are timp de execuie (nk + n lg(n/k)) n cazul
cel mai defavorabil, care este cea mai mare valoare asimptotic a lui k (cu notaia ) n
funcie de n, pentru care algoritmul modificat are acelai timp de execuie ca i sortarea
standard prin interclasare?

d. Cum ar trebui ales k n mod practic?

1-3 Inversiuni
Fie un vector A[1..n] de n numere distincte. Dac i < j i A[i] > A[j], atunci perechea (i, j) se
numete inversiune a lui A.

a. Enumerai cele cinci inversiuni ale vectorului h2, 3, 8, 6, 1i.

b. Ce vector avnd elemente din mulimea {1, 2, . . . , n} are cele mai multe inversiuni? Ct de
multe?

c. Care este relaia dintre timpul de execuie al sortrii prin inserie i numrul de inversiuni
din vectorul de intrare? Justificai rspunsul.

d. Descriei un algoritm care determin numrul de inversiuni din orice permutare de n


elemente avnd timp de execuie (n lg n) n cazul cel mai defavorabil. (Indicaie: Mo-
dificai sortarea prin interclasare.)

Note bibliografice
Exist multe texte excelente n legtur cu subiectul general al algoritmilor, inclusiv cele
scrise de Aho, Hopcroft i Ullman [4, 5], Baase [14], Brassard i Bratley [33], Horowitz i Sahni
[105], Knuth [121, 122, 123], Manber [142], Mehlhorn [144, 145, 146], Purdom i Brown [164],
Reingold, Nievergelt i Deo [167], Sedgewick [175] i Wilf [201]. Unele aspecte mai practice ale
proiectrii algoritmilor sunt discutate de Bentley [24, 25] i Gonnet [90].
n 1968, Knuth a publicat primul din cele trei volume cu titlul general Arta Programrii
Calculatoarelor [121, 122, 123]. Primul volum a abordat studiul modern al algoritmilor cu
focalizare pe analiza timpului de execuie, iar aceast serie a rmas o referin semnificativ
pentru multe din problematicile prezentate aici. Conform lui Knuth, cuvntul algoritm este
derivat din numele al-Khowrizm, un matematician persan din secolul IX.
Note bibliografice 17

Aho, Hopcroft i Ullman [4] au susinut analiza asimptotic a algoritmilor ca mijloc de


comparare a performanei relative. Ei au popularizat utilizarea relaiilor de recuren pentru a
descrie timpii de execuie ai algoritmilor recursivi.
Knuth [123] prezint o tratare enciclopedic a multor algoritmi de sortare. Comparaia
algoritmilor de sortare (capitolul 9) include analize exacte ale numrrii pailor, precum aceea
care am efectuat-o aici pentru sortarea prin inserie. Discuia lui Knuth despre sortarea prin
inserie conine cteva variaii ale algoritmului. Cea mai important este sortarea lui Shell,
introdus de D. L. Shell, care utilizeaz sortarea prin inserie pe subiruri periodice ale datelor
de intrare pentru a produce un algoritm de sortare mai rapid.
Sortarea prin interclasare este, de asemenea, descris de Knuth. Acesta menioneaz c
J. von Neumann a inventat n anul 1938 un mecanism capabil s interclaseze dou pachete
de cartele perforate ntr-un singur pas. J. von Neumann, unul dintre pionierii informaticii, se
pare c a scris n 1945 un program pentru sortarea prin interclasare pe calculatorul EDVAC.
I Fundamente matematice
Introducere
Analiza algoritmilor necesit deseori utilizarea uneltelor matematice. Aceste unelte uneori
sunt foarte simple, cum ar fi algebra de liceu, dar altele, cum ar fi rezolvarea recurenelor s-ar
putea s reprezinte o noutate. Aceast parte a crii este un compendiu al metodelor i uneltelor
pe care n aceast carte le vom folosi pentru analiza algoritmilor.
V sugerm s nu ncercai s asimilai toat matematica din acest capitol dintr-o dat.
Rsfoii capitolele din aceast parte pentru a vedea ce conin. Apoi putei trece direct la capitolele
care se ocup de algoritmi. Pe msur ce citii aceste capitole, revenii la aceast parte oricnd
avei nevoie de o mai bun nelegere a uneltelor folosite n analizele de factur matematic.
Oricum, la un moment dat, vei dori s studiai fiecare din aceste capitole n ntregime, astfel
nct s v formai fundamente matematice solide.
Capitolul 2 definete riguros mai multe notaii asimptotice, de exemplu notaia folosit n
capitolul 1. n restul capitolului 2 sunt prezentate alte notaii matematice. Scopul este mai mult
de a asigura faptul c modul n care folosii notaiile matematice este acelai cu cel folosit n
carte, i nu de a v nva noi noiuni matematice.
Capitolul 3 ofer metode pentru evaluarea i mrginirea sumelor, operaii ce apar foarte des
n analiza algoritmilor.
n capitolul 4 sunt prezentate metode de rezolvare a recurenelor, pe care le-am folosit, de
exemplu, pentru a analiza sortarea prin interclasare n capitolul 1 i cu care ne vom ntlni de
multe ori. O tehnic foarte eficient, care poate fi folosit pentru a rezolva recurene ce apar n
algoritmi divide i stpnete, este metoda master. O mare parte din capitolul 4 este alocat
demonstrrii corectitudinii metodei master, dei cititorul poate sri peste aceast demonstraie
fr o pierdere prea mare.
Capitolul 5 conine definiii i notaii de baz pentru mulimi, relaii, funcii, grafuri i arbori.
Acest capitol prezint de asemenea i unele proprieti de baz ale acestor concepte matematice.
Acest material este esenial pentru nelegerea crii, dar poate fi ignorat fr probleme dac ai
studiat anterior un curs de matematic discret.
Capitolul 6 ncepe cu principii elementare de numrare: permutri, combinri i alte noiuni
asemntoare. Restul capitolului conine definiii i proprieti elementare de probabilitate. Cei
mai muli algoritmi din aceast carte nu necesit estimri probabilistice pentru analiza lor, deci
putei omite cu uurin ultimele seciuni la o prim lectur, chiar fr a le rsfoi. Ulterior, cnd
vei ntlni o analiz probabilistic pe care dorii s o nelegei mai bine, vei constata c acest
capitol este bine organizat n acest sens.
2 Creterea funciilor

Ordinul de cretere a timpului de execuie al unui algoritm, definit n capitolul 1 d o


caracterizare simpl pentru eficiena algoritmilor i ne d n acelai timp posibilitatea de a
compara performanele relative ale unor algoritmi alternativi. De ndat ce dimensiunea n a
datelor de intrare devine suficient de mare, algoritmul de sortare prin interclasare, cu timpul de
execuie (n lg n) n cazul cel mai defavorabil, este mai performant dect sortarea prin inserie,
al crei timp de execuie n cazul cel mai defavorabil este (n2 ). Dei uneori se poate determina
exact timpul de execuie al unui algoritm, aa cum am fcut pentru sortarea prin inserie n
capitolul 1, n general, o precizie suplimentar nu merit efortul fcut. Pentru date de intrare
suficient de mari, constantele multiplicative i termenii de ordin inferior din expresia exact a
unui timp de execuie sunt dominai de efectele dimensiunii datelor de intrare n sine.
Cnd examinm date de intrare de dimensiuni suficient de mari, astfel nct numai ordinul
de cretere a timpului de execuie s fie relevant, studiem eficiena asimptotic a algoritmilor.
Cu alte cuvinte, suntem interesai de modul de cretere a timpului de execuie a unui algoritm
o dat cu mrirea dimensiunii datelor de intrare, n cazul limit cnd dimensiunea datelor de
intrare crete nemrginit. n mod uzual, un algoritm care este asimptotic mai eficient va fi cea
mai bun alegere, cu excepia cazului n care datele de intrare sunt de dimensiune foarte mic.
Acest capitol ofer mai multe metode standard pentru simplificarea analizei asimptotice a
algoritmilor. Seciunea urmtoare ncepe prin a defini mai multe tipuri de notaie asimptotic,
dintre care am ntlnit deja -notaia. Vor fi prezentate mai multe convenii de notaie care vor
fi utilizate pe parcursul crii i n final vom trece n revist comportamentul funciilor care apar
frecvent n analiza algoritmilor.

2.1. Notaia asimptotic


Notaiile pe care le utilizm pentru a descrie timpul asimptotic de execuie al unui algoritm
sunt definite cu ajutorul unor funcii al cror domeniu de definiie este de fapt mulimea nu-
merelor naturale N = {0, 1, 2, . . .}. Astfel de notaii sunt convenabile pentru a descrie funcia
timp de execuie n cazul cel mai defavorabil T (n) care n mod uzual este definit doar pentru
dimensiuni ntregi ale datelor de intrare. Totui, este necesar uneori s folosim n mod abuziv
notaia asimptotic ntr-o varietate de moduri. De exemplu, notaia se extinde cu uurin la
domeniul numerelor reale sau, alternativ, se poate restrnge la o submulime a mulimii nume-
relor naturale. Este important totui s nelegem sensul exact al notaiei pentru ca atunci cnd
este utilizat n mod abuziv s nu fie utilizat n mod incorect. n aceast seciune se definesc
principalele notaii asimptotice i de asemenea, se introduc cteva abuzuri de notaie mai des
ntlnite.

-notaia
n capitolul 1 am artat c timpul de execuie pentru sortarea prin inserie n cazul cel mai
defavorabil este T (n) = (n2 ). S definim acum exact aceast notaie. Pentru o funcie dat
2.1. Notaia asimptotic 21

g(n), notm cu (g(n)), mulimea de funcii


(g(n)) = { f (n) : exist constantele pozitive c1 , c2 i n0 astfel nct
0 c1 g(n) f (n) c2 g(n) pentru orice n n0 }.
O funcie f (n) aparine mulimii (g(n)) dac exist constantele pozitive c1 i c2 astfel nct
aceasta s fie plasat ntre c1 g(n) i c2 g(n) pentru n suficient de mare. Dei (g(n)) este o
mulime, vom scrie f (n) = (g(n)) pentru a indica faptul c f (n) este un membru al acesteia.
Acest abuz al utilizrii semnului de egalitate pentru a desemna apartenena la o mulime poate
s par confuz la nceput, dar vom vedea mai trziu c are avantajele sale.
Figura 2.1 (a) d o imagine intuitiv a funciilor f (n) i g(n), cnd f (n) = (g(n)). Pentru
toate valorile lui n aflate la dreapta lui n0 , valoarea lui f (n) este mai mare sau egal cu c1 g(n)
i mai mic sau egal cu c2 g(n). Cu alte cuvinte, pentru orice n n0 , s-ar putea spune c
funcia f (n) este egal cu g(n) pn la un factor constant. Vom spune c g(n) este o margine
asimptotic tare pentru f (n).
Definiia lui (g(n)) cere ca orice membru f (n) (g(n)) s fie asimptotic nenegativ ,
adic f (n) s fie nenegativ pentru n destul de mare. O funcie asimptotic pozitiv este strict
pozitiv pentru orice n suficient de mare. Prin urmare, funcia g(n) nsi ar trebui s fie
nenegativ, altfel mulimea (g(n)) este vid. Din acest motiv vom presupune n continuare
c orice funcie utilizat n cadrul -notaiei este asimptotic nenegativ. Aceast presupunere
rmne valabil i pentru celelalte notaii asimptotice definite n acest capitol.
n capitolul 1 am introdus o noiune neriguroas de -notaie care ducea la neglijarea
termenilor de ordin inferior i a coeficientului constant al termenului de ordin maxim. S justi-
ficm pe scurt aceast imagine intuitiv, utiliznd de data aceasta definiia, pentru a arta c
1 2 2
2 n 3n = (n ). Pentru a face aceasta, trebuie determinate constantele pozitive c1 , c2 i n0
astfel nct
1 2
c1 n2 n 3n c2 n2
2
pentru orice n n0 . mprind cu n2 , se obine
1 3
c1 c2 .
2 n
Inegalitatea din dreapta va fi verificat pentru orice n 1 dac alegem c2 1/2. n acelai fel,
inegalitatea din stnga va fi verificat pentru orice valoare n 7 dac alegem c1 1/14. Astfel,
lund c1 = 1/14, c2 = 1/2 i n0 = 7, se poate verifica faptul c 12 n2 3n = (n2 ). Evident,
sunt posibile i alte alegeri pentru aceste constante, ns faptul important aici este doar acela c
acestea exist. S mai observm c aceste constante depind de funcia 21 n2 3n; o alt funcie
aparinnd lui (n2 ) va cere de regul alte constante.
Putem utiliza definiia formal i pentru a verifica faptul c 6n3 6= (n2 ). S presupunem, n
scopul obinerii unei contradicii, c exist c2 i n0 astfel nct 6n3 c2 n2 pentru orice n n0 .
De aici, n c2 /6, inegalitate care nu poate fi adevrat pentru n orict de mare deoarece c2
este o constant.
Intuitiv, termenii de ordin inferior ai unei funcii asimptotic pozitive pot fi ignorai n
determinarea unor margini asimptotic strnse, deoarece acetia sunt nesemnificativi pentru valori
mari ale lui n. O fraciune infim a termenului de rang maxim este suficient pentru a domina
termenii de rang inferior. Astfel, dnd lui c1 o valoare ceva mai mic dect coeficientul termenului
22 Capitolul 2 Creterea funciilor

Figura 2.1 Exemple grafice pentru notaiile , O i . n fiecare parte, valoarea indicat a lui n0
este cea mai mic valoare posibil; orice valoare mai mare va funciona, de asemenea. (a) -notaia
mrginete o funcie pn la factori constani. Scriem f (n) = (g(n)) dac exist constantele pozitive
n0 , c1 i c2 astfel nct la dreapta lui n0 , valoarea lui f (n) se afl ntotdeauna ntre c1 g(n) i c2 g(n)
inclusiv. (b) O-notaia d o margine superioar pentru o funcie pn la un factor constant. Scriem
f (n) = O(g(n)) dac exist constantele pozitive n0 i c astfel nct la dreapta lui n0 , valoarea lui f (n)
este ntotdeauna mai mic sau egal cu cg(n). (c) -notaia d o margine inferioar pentru o funcie
pn la un factor constant. Scriem f (n) = (g(n)) dac exist constantele pozitive n0 i c astfel nct
la dreapta lui n0 , valoarea lui f (n) este ntotdeauna mai mare sau egal cu cg(n).

de rang maxim i dnd lui c2 o valoare ceva mai mare, s-ar putea ca inegalitile din definiia -
notaiei s fie satisfcute. Coeficientul termenului de rang maxim poate fi de asemenea ignorat,
deoarece acesta poate schimba c1 i c2 doar cu un factor constant.
Pentru a exemplifica, s considerm o funcie ptratic oarecare f (n) = an2 + bn + c, n
care a, b i c sunt constante iar a > 0. Eliminarea termenilor de rang inferior lui 2 i neglijarea
constantelor conduce la f (n) = (n2 ). Pentru a artapacelai lucru n mod formal, alegem
constantele c1 = a/4, c2 = 7a/4 i n0 = 2 max{|b|/a, |c|/a}. Cititorul poate arta c 0
c1 n2 an2 + bn + c c2 n2 pentru orice n n0 . n general, pentru orice polinom p(n) =
Pd i d
i=0 ai x , unde ai sunt constante i ad > 0, avem p(n) = (n ). (vezi problema 2-1)
Deoarece orice constant este un polinom de gradul 0, putem expima orice funcie constant
ca (n0 ) sau (1). Aceast ultim notaie este un mic abuz deoarece nu este clar care variabil
tinde la infinit.1 Vom folosi des notaia (1) nelegnd prin aceasta fie o constant, fie o funcie
constant.

O-notaia
-notaia delimiteaz o funcie asimptotic inferior i superior. Cnd avem numai o margine
asimptotic superioar, utilizm O-notaia. Fiind dat o funcie g(n), vom nota cu O(g(n)),

1 Adevrata problem este aceea c notaia noastr obinuit pentru funcii nu face distincie ntre funcii i

valorile lor. n -calcul, parametrii unei funcii sunt clar specificai: funcia n2 poate fi scris ca n n2 sau chiar
r r2 . Adoptarea unei notaii mai riguroase, pe de alt parte, ar complica manipulrile algebrice, aa c preferm
s tolerm abuzul.
2.1. Notaia asimptotic 23

mulimea

O(g(n)) = {f (n) : exist constantele pozitive c i n0 astfel nct


0 f (n) cg(n) pentru orice n n0 }.

Vom utiliza O-notaia pentru a indica o margine superioar a unei funcii pn la un factor
constant. Figura 2.1(b) d imaginea intuitiv aflat n spatele O-notaiei. Pentru toate valorile
lui n aflate la dreapta lui n0 , valorile corespunztoare ale lui f (n) sunt egale sau mai mici dect
cele ale lui g(n).
Pentru a indica faptul c o funcie f (n) este un membru al lui O(g(n)), vom scrie f (n) =
O(g(n)). S notm faptul c f (n) = (g(n)) implic f (n) = O(g(n)) deoarece -notaia este o
noiune mai puternic dect O-notaia. n limbajul teoriei mulimilor, avem (g(n)) O(g(n)).
Astfel, demonstraia faptului c orice funcie ptratic an2 + bn + c, unde a > 0, n (n2 ), arat
de asemenea c orice funcie ptratic este n O(n2 ). Ceea ce poate prea i mai surprinztor
este c orice funcie liniar an + b este n O(n2 ), ceea ce se verific uor, lund c = a + |b| i
n0 = 1.
Unor cititori, care s-au mai ntlnit cu notaii de tipul O, ar putea s li se par ciudat c
scriem n = O(n2 ). n literatur, O-notaia este folosit uneori informal pentru a descrie margini
asimptotice strnse, adic ceea ce am definit utiliznd -notaia. n aceast carte, totui, atunci
cnd scriem f (n) = O(g(n)), afirmm, n esen, c un anumit multiplu constant al lui g(n)
este o margine asimptotic superioar a lui f (n), fr s spunem nimic despre ct de strns
este aceast margine superioar. Distincia dintre marginile asimptotice superioare i marginile
asimptotice strnse a devenit standard n literatura consacrat algoritmilor.
Folosind O-notaia, se poate adeseori descrie timpul de execuie al unui algoritm inspectnd
structura global a algoritmului. De exemplu, structura de ciclu dublu a algoritmului de sortare
prin inserie din capitolul 1 asigur imediat o margine superioar de tipul O(n2 ) pentru timpul
de execuie n cazul cel mai defavorabil: costul ciclului interior este mrginit superior de O(1)
(constant), indicii i, j sunt, ambii, cel mult n iar ciclul interior este executat cel mult o dat
pentru fiecare dintre cele n2 perechi de valori pentru i i j.
Deoarece O-notaia descrie o margine superioar, atunci cnd o folosim pentru delimitarea
timpului de execuie n cazul cel mai defavorabil, prin implicaie, delimitm, de asemenea, timpul
de execuie al algoritmului pentru date de intrare arbitrare. Astfel, delimitarea O(n2 ) pentru
timpul de execuie n cazul cel mai defavorabil al sortrii prin inserie se aplic, n egal msur,
timpului su de execuie pentru orice date de intrare. Delimitarea (n2 ) a timpului de execuie
n cazul cel mai defavorabil al sortrii prin inserie, totui, nu implic o delimitare (n2 ) asupra
timpului de execuie al sortrii prin inserie pentru orice date de intrare. De exemplu, am vzut
n capitolul 1 c dac datele de intrare sunt deja sortate, sortarea prin inserie se execut n
timpul (n).
Tehnic, este o inexactitate s se spun c timpul de execuie la sortarea prin inserie este
O(n2 ) deoarece pentru un n dat timpul real de execuie depinde de forma datelor de intrare
de dimensiune n. Prin urmare, timpul de execuie nu este de fapt tocmai o funcie de n. Ceea
ce nelegem atunci cnd spunem timpul de execuie este O(n2 ) este c timpul de execuie n
cazul cel mai defavorabil (care este o funcie de n) este O(n2 ), sau, echivalent, oricare ar fi datele
de intrare de dimensiune n, pentru fiecare valoare a lui n, timpul de execuie pentru acest set
de date de intrare este O(n2 ).
24 Capitolul 2 Creterea funciilor

-notaia
La fel cum O-notaia furnizeaz o delimitare asimptotic superioar pentru o funcie, -
notaia furnizeaz o delimitare asimptotic inferioar. Pentru o funcie dat g(n), vom
nota cu (g(n)), mulimea

(g(n)) = {f (n) : exist constantele pozitive c i n0 astfel nct


0 cg(n) f (n) pentru orice n n0 }

Imaginea intuitiv n spatele -notaiei este artat n figura 2.1(c). Pentru toate valorile n aflate
la dreapta lui n0 , f (n) este mai mare sau egal cu cg(n).
Din definiiile notaiilor asimptotice pe care le-am ntlnit pn acum, este uor de demonstrat
urmtoarea teorem important (vezi exerciiul 2.1-5).

Teorema 2.1 Pentru orice dou funcii f (n) i g(n), avem f (n) = (g(n)) dac i numai dac
f (n) = O(g(n)) i f (n) = (g(n)).

Ca un exemplu de aplicare a acestei teoreme, faptul c an2 + bn + c = (n2 ) implic imediat


an + bn + c = O(n2 ) i an2 + bn + c = (n2 ). n practic, n loc s utilizm teorema 2.1 pentru a
2

obine margini asimptotice superioare sau inferioare pornind de la margini asimptotice strnse,
aa cum am fcut n exemplul precedent, o utilizm de obicei pentru a demonstra delimitri
asimptotice strnse plecnd de la delimitri asimptotice superioare i inferioare. Mrginirea
asimptotic tare va fi demonstrat utiliznd mrginirea asimptotic, superioar i inferioar.
Deoarece -notaia descrie o margine inferioar, atunci cnd o utilizm pentru a evalua
timpul de execuie al unui algoritm n cazul cel mai favorabil, n mod implicit, evalum i timpul
de execuie al algoritmului pentru date de intrare arbitrare. De exemplu, timpul de execuie n
cazul cel mai favorabil al sortrii prin inserie este (n), de unde rezult c timpul de execuie
al sortrii prin inserie este (n).
Timpul de execuie al sortrii prin inserie se afl prin urmare ntre O(n) i (n2 ) deoarece
este situat ntotdeauna ntre o funcie liniar i o funcie ptratic de n. Mai mult, aceste
aproximri sunt asimptotic cele mai strnse: de exemplu, timpul de execuie al sortrii prin
inserie nu este (n2 ) deoarece acesta este (n) n cazul datelor de intrare deja sortate. Nu este
contradictoriu s spunem totui c acest timp de execuie este (n2 ) n cazul cel mai defavorabil
deoarece exist cel puin un tip de date de intrare care impun algoritmului un timp de execuie
(n2 ). Atunci cnd spunem c timpul de execuie al unui algoritm este (g(n)), nelegem c
nu conteaz ce set particular de date de intrare de dimensiune n este ales pentru fiecare valoare
a lui n, timpul de execuie pe acel set de date de intrare este cel puin o constant nmulit cu
g(n), pentru n suficient de mare.

Notaia asimptotic n ecuaii


Am vzut deja cum poate fi utilizat o notaie asimptotic n formulele matematice. De
exemplu, la introducerea O-notaiei, am scris n = O(n2 ). Am putea scrie, de asemenea 2n2 +
3n + 1 = 2n2 + (n). Cum interpretm astfel de formule?
Atunci cnd o notaie asimptotic se afl singur n membrul drept al unei ecuaii, ca n n =
O(n2 ), deja am definit semnul de egalitate ca reprezentnd apartenena din teoria mulimilor:
n O(n2 ). n general, totui, cnd notaia asimptotic apare ntr-o relaie, o vom interpreta
2.1. Notaia asimptotic 25

ca reprezentnd o funcie anonim pe care nu ne obosim s o numim. De exemplu, egalitatea


2n2 + 3n + 1 = 2n2 + (n) nseamn de fapt 2n2 + 3n + 1 = 2n2 + f (n), unde f (n) este o funcie
oarecare din mulimea (n). n acest caz, f (n) = 3n + 1, care este ntr-adevr n (n).
Folosirea notaiilor asimptotice n aceste situaii poate ajuta la eliminarea unor detalii inutile
dintr-o ecuaie. De exemplu, n capitolul 1, am exprimat timpul de execuie n cazul cel mai
defavorabil la sortarea prin interclasare prin relaia de recuren
T (n) = 2 T (n/2) + (n)
Dac suntem interesai doar de comportarea asimptotic a lui T (n), nu are nici un rost s
specificm exact toi termenii de ordin inferior: acetia sunt toi presupui a fi inclui n funcia
anonim notat prin termenul (n).
Numrul funciilor "anonime" ntr-o expresie este neles ca fiind egal cu numrul notaiilor
asimptotice care apar n aceast expresie. De exemplu, n expresia
X n
O(i)
i=1

exist o singur funcie anonim (o funcie de i). Aceast expresie nu este echivalent cu O(1) +
O(2) + + O(n), care oricum nu are o interpretare clar.
n anumite cazuri apar notaii asimptotice n membrul stng al unei ecuaii, cum ar fi
2n2 + (n) = (n2 ).
Vom interpreta astfel de ecuaii utiliznd urmtoarea regul: Oricum ar fi alese funciile anonime
din partea stng a semnului egal, exist o modalitate de alegere a funciilor anonime din partea
dreapt a semnului egal pentru a realiza egalitatea descris de ecuaie. Astfel, sensul exemplului
nostru este acela c pentru orice funcie f (n) (n), exist o anumit funcie g(n) (n2 )
astfel nct 2n2 + f (n) = g(n) pentru orice n. Cu alte cuvinte, membrul drept al ecuaiei ofer
un nivel de detaliu mai sczut dect membrul stng.
Un numr de astfel de relaii pot fi nlnuite ca n
2n2 + 3n + 1 = 2n2 + (n) = (n2 )
Putem interpreta fiecare ecuaie separat dup regula de mai sus. Prima ecuaie spune c exist o
funcie f (n) (n) astfel nct 2n2 + 3n + 1 = 2n2 + f (n) pentru orice n. A doua ecuaie spune
c pentru orice funcie g(n) (n) (aa cum este f (n)), exist o anumit funcie h(n) (n2 )
astfel nct 2n2 + g(n) = h(n) pentru orice n. S observm c aceast interpretare implic
2n2 + 3n + 1 = (n2 ), fapt care coincide cu informaia intuitiv pe care o transmite lanul celor
dou ecuaii de mai sus.

o-notaia
Delimitarea asimptotic superioar dat de O-notaia definit anterior poate sau nu s fie o
delimitare asimptotic strns. Astfel, relaia 2n2 = O(n2 ), este o delimitare asimptotic strns
pe cnd 2n = O(n2 ) nu este. Vom utiliza n cele ce urmeaz o-notaia pentru a desemna o
delimitare superioar care nu este asimptotic strns. Formal, vom defini o(g(n)) (o mic de g
de n) ca fiind mulimea
o(g(n)) = {f (n) : pentru orice constant pozitiv c > 0 exist o constant
n0 > 0 astfel nct 0 f (n) < cg(n) pentru orice n n0 }.
26 Capitolul 2 Creterea funciilor

De exemplu, 2n = o(n2 ), dar 2n2 6= o(n2 ).


Definiiile pentru O-notaie i o-notaie sunt similare. Principala diferen este aceea c n
f (n) = O(g(n)), delimitarea 0 f (n) c g(n) are loc pentru o anumit constant c > 0, dar,
n f (n) = o(g(n)), delimitarea 0 f (n) < c g(n) are loc pentru toate constantele c > 0. Intuitiv,
n cazul o-notaiei, funcia f (n) devine neglijabil relativ la g(n) atunci cnd n tinde la infinit;
cu alte cuvinte
f (n)
lim = 0. (2.1)
n g(n)
Unii autori folosesc aceast limit ca o definiie pentru o-notaie: definiia din aceast carte
impune, de asemenea, funciilor anonime s fie asimptotic nenegative.

-notaia
Prin analogie, -notaia este fa de -notaie ceea ce este o-notaia fa de O-notaie.
Utilizm -notaia pentru a desemna o delimitare asimptotic inferioar care nu este asimptotic
strns. O cale de a o defini este
f (n) (g(n)) dac i numai dac g(n) o(f (n)).
Formal, totui, definim (g(n)) ("omega mic de g de n") ca fiind mulimea
(g(n)) = {f (n) : pentru orice constant pozitiv c > 0 exist o constant
n0 > 0 astfel nct 0 cg(n) < f (n) pentru orice n n0 }.
De exemplu, n2 /2 = (n), dar n2 /2 6= (n). Relaia f (n) = (g(n)) implic
f (n)
lim = ,
n g(n)
dac limita exist. Cu alte cuvinte, f (n) devine orict de mare relativ la g(n) atunci cnd n
tinde la infinit.

Compararea funciilor
Multe dintre proprietile relaiilor dintre numerele reale se aplic i la compararea asimpto-
tic a funciilor. Pentru cele ce urmeaz vom presupune c f (n) i g(n) sunt asimptotic pozitive.
Tranzitivitatea:
f (n) = (g(n)) i g(n) = (h(n)) implic f (n) = (h(n)),
f (n) = O(g(n)) i g(n) = O(h(n)) implic f (n) = O(h(n)),
f (n) = (g(n)) i g(n) = (h(n)) implic f (n) = (h(n)),
f (n) = o(g(n)) i g(n) = o(h(n)) implic f (n) = o(h(n)),
f (n) = (g(n)) i g(n) = (h(n)) implic f (n) = (h(n)).
Reflexivitatea:
f (n) = (f (n)),
f (n) = O(f (n)),
f (n) = (f (n)).
2.1. Notaia asimptotic 27

Simetria:
f (n) = (g(n)) dac i numai dac g(n) = (f (n)).
Antisimetria:
f (n) = O(g(n)) dac i numai dac g(n) = (f (n)),
f (n) = o(g(n)) dac i numai dac g(n) = (f (n)).
Deoarece aceste proprieti sunt valide pentru notaii asimptotice, se poate trasa o analogie
ntre compararea asimptotic a dou funcii f i g i compararea asimptotic a dou numere
reale a i b:
f (n) = O(g(n)) a b,
f (n) = (g(n)) a b,
f (n) = (g(n)) a = b,
f (n) = o(g(n)) a < b,
f (n) = (g(n)) a > b.

O proprietate a numerelor reale, totui, nu se transpune la notaii asimptotice:


Trihotomia: Pentru orice dou numere reale a i b exact una dintre urmtoarele relaii este
adevrat: a < b, a = b sau a > b.
Dei orice dou numere reale pot fi comparate, nu toate funciile sunt asimptotic comparabile.
Cu alte cuvinte, pentru dou funcii f (n) i g(n), se poate ntmpla s nu aib loc nici f (n) =
O(g(n)), nici f (n) = (g(n)). De exemplu, funciile n i n1+sin n nu pot fi comparate utiliznd
notaii asimptotice, deoarece valoarea exponentului n n1+sin n oscileaz ntre 0 i 2, lund toate
valorile intermediare.

Exerciii
2.1-1 Fie f (n) i g(n) funcii asimptotic nenegative. Utiliznd definiia de baz a -notaiei,
demonstrai c max(f (n), g(n)) = (f (n) + g(n)).

2.1-2 Demonstrai c pentru orice constante reale a i b, unde b > 0, avem


(n + a)b = (nb ). (2.2)

2.1-3 Explicai de ce afirmaia Timpul de execuie al algoritmului A este cel puin O(n2 ) este
lipsit de coninut.

2.1-4 Este adevrat c 2n+1 = O(2n )? Este adevrat c 22n = O(2n )?

2.1-5 Demonstrai teorema 2.1.

2.1-6 Demonstrai c timpul de execuie al unui algoritm este (g(n)) dac i numai dac
timpul su de execuie n cazul cel mai defavorabil este O(g(n)) i timpul su de execuie n
cazul cel mai favorabil este (g(n)).

2.1-7 Demonstrai c o(g(n)) (g(n)) este mulimea vid.


28 Capitolul 2 Creterea funciilor

2.1-8 Putem extinde notaia noastr la cazul a doi parametri n i m care tind la infinit n mod
independent, cu viteze diferite. Peentru o funcie dat g(n, m) notm cu O(g(n, m)) mulimea
de funcii

O(g(n, m)) = {f (n, m) : exist constantele pozitive c, n0 i m0 astfel nct


0 f (n, m) cg(n, m) pentru orice n n0 i m m0 }.

Dai definiiile corespunztoare pentru (g(n, m)) i (g(n, m)).

2.2. Notaii standard i funcii comune


Aceast seciune trece n revist cteva funcii i notaii matematice standard i exploreaz
relaiile dintre ele. Ea ilustreaz, de asemenea, utilizarea notaiilor asimptotice.

Monotonie
O funcie f (n) este monoton cresctoare dac m n implic f (m) f (n). Analog, ea
este monoton descresctoare dac m n implic f (m) f (n). O funcie f (n) este strict
cresctoare dac m < n implic f (m) < f (n) i strict descresctoare dac m < n implic
f (m) > f (n).

Pri ntregi inferioare i superioare


Pentru orice numr real x, notm cel mai mare ntreg mai mic sau egal cu x prin bxc (se
citete partea ntreag inferioar a lui x) i cel mai mic ntreg mai mare sau egal cu x prin dxe
(se citete partea ntreag superioar a lui x). Pentru orice x real,

x 1 < bxc x dxe < x + 1.

Pentru orice ntreg n,

dn/2e + bn/2c = n,

iar pentru orice ntreg n i orice ntregi a 6= 0 i b > 0,

ddn/ae/be = dn/abe (2.3)

bbn/ac/bc = bn/abc. (2.4)

Funciile parte ntreag inferioar i superioar sunt monoton cresctoare.


2.2. Notaii standard i funcii comune 29

Polinoame
Fiind dat un ntreg pozitiv d, un polinom n n de gradul d este o funcie p(n) de forma
d
X
p(n) = ai ni ,
i=0

unde constantele a0 , a1, . . . ad sunt coeficienii polinomului, iar ad 6= 0. Un polinom este


asimptotic pozitiv dac i numai dac ad > 0. Pentru un polinom asimptotic pozitiv p(n) de grad
d avem p(n) = (nd ). Pentru orice constant real a 0, funcia na este monoton cresctoare,
iar pentru orice constant real a 0 funcia na este monoton descresctoare. Spunem c o
funcie f (n) este polinomial mrginit dac f (n) = nO(1) , ceea ce este echivalent cu a spune
c f (n) = O(nk ) pentru o anumit constant k (vezi exerciiul 2.2-2).

Exponeniale
Pentru orice a 6= 0, m i n reale avem urmtoarele identiti:
a0 = 1,
a1 = a,
a1 = 1/a,
m n
(a ) = amn ,
(am )n = (an )m ,
am an = am+n .
Pentru orice n i a 1, funcia an este monoton cresctoare n n. Cnd ne va conveni, vom
presupune c 00 = 1.
Ratele de cretere ale polinoamelor i exponenialelor pot fi legate prin urmtorul fapt. Pentru
orice constante a i b astfel nct a > 1,
nb
lim = 0, (2.5)
n an

din care putem trage concluzia c


nb = o(an ).
Astfel, orice funcie exponenial avnd baza strict mai mare dect 1 crete mai repede dect
orice funcie polinomial.
Utiliznd e pentru a nota 2.71828 . . ., baza funciei logaritm natural, avem, pentru orice x
real,

X xi
x2 x3
ex = 1 + x + + + = , (2.6)
2! 3! i=0
i!

unde ! desemneaz funcia factorial definit mai trziu n aceast seciune. Pentru orice x real
avem inegalitatea
ex 1 + x, (2.7)
30 Capitolul 2 Creterea funciilor

unde egalitatea are loc numai pentru x = 0. Cnd |x| 1, avem aproximaia
1 + x ex 1 + x + x2 . (2.8)
Cnd x 0, aproximaia lui ex prin 1 + x este destul de bun:
ex = 1 + x + (x2 ).
(n aceast ecuaie, notaia asimptotic este utilizat pentru a descrie comportamentul la limit
pentru x 0 mai degrab dect pentru x .) Avem, pentru orice x,
x n
lim 1 + = ex .
n n

Logaritmi
Vom utiliza urmtoarele notaii:
lg n = log2 n (logaritm binar),
ln n = loge n (logaritm natural),
lgk n = (lg n)k (exponenierea),
lg lg n = lg(lg n) (compunerea).
O convenie de notaie important pe care o vom adopta este aceea c funciile logaritmice se
vor aplica numai urmtorului termen dintr-o formul, astfel c lg n + k va nsemna (lg n) + k i
nu lg(n + k). Pentru n > 0 i b > 1, funcia logb n este strict cresctoare.
Pentru orice numere reale a > 0, b > 0, c > 0 i n,
a = blogb a ,
logc (ab) = logc a + logc b,
logb an = n logb a,
logc a
logb a = ,
logc b
logb (1/a) = logb a,
1
logb a = ,
loga b
alogb n = nlogb a . (2.9)
Deoarece schimbarea bazei unui logaritm de la o constant la o alt constant schimb
valoarea logaritmului doar printr-un factor constant, vom utiliza adesea notaia lg n cnd
factorii constani nu vor fi importani, aa cum este cazul cu O-notaia. Informaticienilor li
se pare c 2 este baza cea mai natural pentru logaritmi, deoarece att de muli algoritmi i
structuri de date presupun descompunerea unei probleme n dou pri.
Exist o dezvoltare n serie simpl pentru ln(1 + x) cnd |x| < 1:
x2 x3 x4 x5
ln(1 + x) = x + +
2 3 4 5
Avem, de asemenea, urmtoarele inegaliti pentru x > 1:
x
ln(1 + x) x, (2.10)
1+x
2.2. Notaii standard i funcii comune 31

unde egalitatea are loc numai pentru x = 0.


Spunem c o funcie f (n) este polilogaritmic mrginit dac f (n) = lgO(1) n. Putem lega
creterile polinoamelor i polilogaritmilor nlocuind pe n cu lg n i pe a cu 2a n ecuaia (2.5),
obinnd

lgb n lgb n
lim = lim = 0.
n (2a )lg n n na

Din aceast limit, putem conchide c

lgb n = o(na )

pentru orice constant a > 0. Astfel, orice funcie polinomial pozitiv crete mai repede dect
orice funcie polilogaritmic.

Factoriali
Notaia n! (se citete n factorial) este definit pentru numere ntregi n 0 prin

1 dac n = 0,
n! =
n (n 1)! dac n > 0.
Astfel, n! = 1 2 3 n.
O margine superioar slab a funciei factorial este n! nn , deoarece fiecare dintre cei n
factori ai produsului factorial este cel mult n. Aproximaia lui Stirling,
n n
1
n! = 2n 1+ , (2.11)
e n
unde e este baza logaritmilor naturali, ne d o margine superioar mai strns, dar i o margine
inferioar. Utiliznd aproximaia lui Stirling, putem demonstra c

n! = o(nn ),
n! = (2n ),
lg(n!) = (n lg n).

Urmtoarele delimitri sunt, de asemenea, valabile pentru orice n:


n n n ne1/12n
2n n! 2n (2.12)
e e

Funcia logaritm iterat


Utilizm notaia lg n (se citete logaritm stea de n) pentru a nota logaritmul iterat, care
este definit dup cum urmeaz. Fie funcia lg(i) n definit recursiv pentru ntregii nenegativi i
prin

n dac i = 0,
lg (i) n = lg(lg(i1) n) dac i > 0 i lg(i1) n > 0,

nedefinit dac i > 0 i lg (i1) n 0 sau lg(i1) n este nedefinit.
32 Capitolul 2 Creterea funciilor

Calculai diferena ntre funcia lg(i) n (funcia logaritm aplicat succesiv de i ori, ncepnd cu
argumentul n) i lgi n (logaritmul lui n ridicat la puterea i). Funcia logaritm iterat este definit
prin
n o
lg n = min i 0 : lg(i) n 1 .

Funcia logaritm iterat este o funcie foarte lent cresctoare:

lg 2 = 1,
lg 4 = 2,
lg 16 = 3,
lg 65536 = 4,
lg (265536 ) = 5.

Deoarece numrul atomilor din universul observabil este estimat la aproximativ 1080 , care este
mult mai mic dect 265536 , rareori ntlnim o valoare a lui n astfel nct lg n > 5.

Numere Fibonacci
Numerele Fibonacci sunt definite prin urmtoarea recuren:

F0 = 0, F1 = 1, Fi = Fi1 + Fi2 pentru i 2. (2.13)

Astfel, fiecare numr Fibonacci este suma celor dou numere Fibonacci anterioare, rezultnd
secvena

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, . . . .


b care sunt date de
Numerele Fibonacci sunt legate de raportul de aur i de conjugatul su ,
urmtoarele formule:

1+ 5 b 1 5
= = 1.61803 . . . , = = .61803 . . . . (2.14)
2 2
Mai precis, avem

i bi
Fi = , (2.15)
5

ceea b bi
ce se poate demonstra prin inducie (exerciiul 2.2-7). Deoarece |i|< 1, avem | |/ 5 <
1/ 5 < 1/2, astfel c cel de-al i-lea numr Fibonacci este egal cu / 5 rotunjit la cel mai
apropiat ntreg. Astfel, numerele Fibonacci cresc exponenial.

Exerciii
2.2-1 Artai c dac f (n) i g(n) sunt funcii monoton cresctoare, atunci la fel sunt i funciile
f (n) + g(n) i f (g(n)), iar dac f (n) i g(n) sunt n plus nenegative, atunci i f (n) g(n) este
monoton cresctoare.
Probleme 33

2.2-2 Utilizai definiia O-notaiei pentru a arta c T (n) = nO(1) dac i numai dac exist o
constant k > 0 astfel nct T (n) = O(nk ).

2.2-3 Demonstrai ecuaia (2.9).

2.2-4 Demonstrai c lg(n!) = (n lg n) i c n! = o(nn ).

2.2-5 ? Este funcia dlg ne! polinomial mrginit? Este funcia dlg lg ne! polinomial mrginit?

2.2-6 ? Care este asimptotic mai mare: lg(lg n) sau lg (lg n)?

2.2-7 Demonstrai
prin inducie c cel de-al i-lea numr Fibonacci verific egalitatea Fi =
(i bi )/ 5, unde este raportul de aur iar b este conjugatul su.

2.2-8 Demonstrai c pentru i 0 cel de-al (i + 2)-lea numr Fibonacci verific Fi+2 i .

Probleme
2-1 Comportamentul asimptotic al polinoamelor
Fie
d
X
p(n) = ai pi ,
i=0

unde ad > 0 un polinom de gradul d n n i fie k o constant. Utilizai proprietile notaiilor


asimptotice pentru a demonstra urmtoarele proprieti.

a. Dac k d, atunci p(n) = O(nk ).


b. Dac k d, atunci p(n) = (nk ).
c. Dac k = d, atunci p(n) = (nk ).
d. Dac k > d, atunci p(n) = o(nk ).
e. Dac k < d, atunci p(n) = (nk ).

2-2 Creteri asimptotice relative


Indicai, pentru fiecare pereche de expresii (A, B) din tabelul urmtor, dac A este O, o, ,
sau de B. Presupunei c k 1, > 0 i c > 1 sunt constante. Rspunsul trebuie s fie sub
forma unui tabel, cu da sau nu scrise n fiecare rubric.
A B O o
a. lgk n n
b. nk
cn
c. n nsin n
d. 2n 2n/2
e. nlg m mlg n
f. lg(n!) lg(nn )
34 Capitolul 2 Creterea funciilor

2-3 Ordonarea dup ratele de cretere asimptotic

a. Ordonai urmtoarele funcii dup ordinea de cretere; mai precis, gsii un aranjament de
funcii g1 , g2 , . . . g30 care s verifice g1 = (g2 ), g2 = (g3 ), . . . , g29 = (g30 ). Partiionai
lista n clase de echivalen astfel nct f (n) i g(n) s fie n aceeai clas de echivalen
dac i numai dac f (n) = (g(n)).


lg(lg
3 nn) 2lg n ( 2)lg n n2 n! (lg n)!
n

2 n3 lg2 n lg(n!) 22 n1/ lg n


ln ln n lg n n 2n nlg lg n ln n 1
2lg n (lgn)lg n en 4lg n (n + 1)! lg n
n+1
lg (lg n) 2 2 lg n n 2n n lg n 22

b. Dai un exemplu de o singur funcie nenegativ f (n) astfel nct pentru toate funciile
gi (n) de la punctul (a), f (n) s nu fie nici O(gi (n)) nici (gi (n)).

2-4 Proprieti ale notaiilor asimptotice


Fie f (n) i g(n) funcii asimptotic pozitive. Demonstrai urmtoarele conjecturi sau demonstrai
c ele nu sunt adevrate.
a. f (n) = O(g(n) implic g(n) = O(f (n).
b. f (n) + g(n) = (min(f (n), g(n))).
c. f (n) = O(g(n)) implic lg(f (n)) = O(lg(g(n))), unde lg(g(n)) > 0 i f (n) 1 pentru orice
n suficient de mare.
d. f (n) = O(g(n)) implic 2f (n) = O(2g(n) ).
e. f (n) = O((f (n))2 ).
f. f (n) = O(g(n)) implic g(n) = (f (n)).
g. f (n) = (f (n/2)).
h. f (n) + o(f (n)) = (f (n)).

2-5 Variaii ale lui O i



Unii autori definesc ntr-un mod uor diferit de al nostru; s utilizm (se citete omega

infinit) pentru aceast definiie alternativ. Spunem c f (n) = (g(n)) dac exist o constant
pozitiv c astfel nct f (n) cg(n) 0 pentru infinit de muli n.
a. Artai c pentru oricare dou funcii f (n) i g(n) care sunt asimptotic nenegative, fie

f (n) = O(g(n)), fie f (n) = (g(n)) fie amndou, n timp ce aceast afirmaie nu este

adevrat dac utilizm n loc de .

b. Descriei avantajele i dezavantajele poteniale ale utilizrii lui n locul lui pentru a
descrie timpii de execuie ai programelor.
Note bibliografice 35

Unii autori l definesc i pe O ntr-un mod uor diferit; s utilizm O0 pentru definiia alternativ.
Spunem c f (n) = O0 (g(n)) dac i numai dac |f (n)| = O(g(n)).

c. Ce se ntmpl cu fiecare dintre direciile lui dac i numai dac din teorema 2.1 cu
aceast nou definiie?
(se citete o moale) ca nsemnnd O cu factorii logaritmici ignorai:
Unii autori definesc O

O(g(n)) = {f (n) : exist constantele pozitive, c, k i n0 astfel nct
0 f (n) cg(n) lgk (n) pentru orice n n0 }.
i
d. Definii ntr-un mod analog. Demonstrai proprietatea analog corespunztoare
teoremei 2.1.

2-6 Funcii iterate


Operatorul de iteraie utilizat n funcia lg poate fi aplicat funciilor monoton cresctoare
pe mulimea numerelor reale. Pentru o funcie f care satisface f (n) < n definim funcia f (i)
recursiv pentru numerele ntregi i nenegative prin

f (f ((i1) (n)) dac i > 0,
f (i) (n) =
n dac i = 0.
Pentru o constant dat c R, definim funcia iterat fc prin

fc (n) = min{i 0 : f (i) (n) c},

care nu trebuie s fie bine-definit n toate cazurile. Cu alte cuvinte, cantitatea fc (n) este numrul
de aplicaii iterate ale funciei f necesare pentru a reduce argumentul la c sau la mai puin.
Pentru fiecare dintre urmtoarele funcii f (n) i constantele c, dai o evaluare ct se poate
de strns a lui fc (n).

f (n) c fc (n)
a. lg n 1
b. n1 0
c. n/2 1
d. n/2
2
e. n 2
f. n 1
g. n1/3 2
h. n/ lg n 2

Note bibliografice
Knuth [121] investigheaz originea O-notaiei i afirm c ea apare pentru prima dat ntr-
un text de teoria numerelor al lui P. Bachmann din 1982. o-notaia a fost inventat de ctre E.
Landau n 1909 pentru discuia distribuiei numerelor prime. Notaiile i au fost introduse
de ctre Knuth [124] pentru a corecta practica din literatur, popular dar derutant din punct
de vedere tehnic, de a utiliza O-notaia att pentru margini superioare ct i pentru margini
36 Capitolul 2 Creterea funciilor

inferioare. Mult lume continu s utilizeze O-notaia acolo unde -notaia este mai precis din
punct de vedere tehnic. O alt discuie pe tema istoriei i dezvoltrii notaiilor asimptotice poate
fi gsit n Knuth [121, 124] i Brassard i Bratley [33].
Nu toi autorii definesc notaiile asimptotice n acelai mod, dei diferitele definiii concord
n cele mai comune situaii. Unele dintre definiiile alternative se aplic i la funcii care nu sunt
asimptotic nenegative, dac valorile lor absolute sunt mrginite n mod corespunztor.
Alte proprieti ale funciilor matematice elementare pot fi gsite n orice carte de referin
de matematic, cum ar fi Abramowitz i Stegun [1] sau Beyer [27], sau ntr-o carte de analiz,
cum ar fi Apostol [12] sau Thomas i Finney [192]. Knuth [121] conine o mulime de materiale
despre matematica discret, utilizat n informatic.
3 Sume

Cnd un algoritm conine o structur de control iterativ cum ar fi un ciclu ct timp sau
pentru, timpul su de execuie poate fi exprimat ca suma timpilor necesari la fiecare execuie a
corpului ciclului. De exemplu, am vzut n seciunea 1.2 c a j-a iteraie a sortrii prin inserie a
necesitat un timp proporional cu j n cazul cel mai defavorabil. Adunnd timpii necesari pentru
fiecare iteraie, am obinut o sum (sau serie)
n
X
j.
j=2

Evaluarea sumei a dat o margine (n2 ) pentru timpul de execuie al algoritmului n cazul cel
mai defavorabil. Acest exemplu indic importana general a nelegerii manipulrii i delimitrii
sumelor. (Dup cum vom vedea n capitolul 4, sumele apar i cnd utilizm anumite metode
pentru rezolvarea recurenelor.)
Seciunea 3.1 prezint mai multe formule de baz n care intervin sume. Seciunea 3.2 ofer
tehnici utile pentru delimitarea sumelor. Formulele din seciunea 3.1 sunt date fr demonstraie,
dei demonstraiile pentru unele dintre ele sunt prezentate n seciunea 3.2, pentru a ilustra
metodele acelei seciuni. Majoritatea celorlalte demonstraii pot fi gsite n orice manual de
analiz.

3.1. Formule de nsumare i proprieti


Fiind dat un ir de numere a1 , a2 , . . ., suma finit a1 + a2 + . . . + an poate fi scris
Xn
ak .
k=1
Dac n = 0, valoarea sumei este definit ca fiind 0. Dac n nu este un numr ntreg, mai
presupunem c limita superioar este bnc. Analog, dac suma ncepe cu k = x, unde x nu este
un ntreg, presupunem c valoarea iniial pentru nsumare este bxc. (n general, vom scrie n
mod explicit prile ntregi inferioare sau superioare). Valoarea unei serii finite este ntotdeauna
bine definit, iar termenii si pot fi adunai n orice ordine.
Fiind dat un ir de numere a1 , a2 , . . ., suma infinit a1 + a2 + . . . poate fi scris

X
ak ,
k=1
care este interpretat ca
Xn
lim ak .
n
k=1
Dac limita nu exist, seria diverge; altfel, ea converge. Termenii unei serii convergente nu
pot fi ntotdeauna adunai n orice
Pordine. Putem rearanja,Ptotui, termenii unei serii absolut

convergente, care este o serie k=1 ak pentru care seria k=1 |ak | converge de asemenea.
38 Capitolul 3 Sume

Liniaritate
Pentru orice numr real c i orice iruri finite a1 , a2 , . . . , an i b1 , b2 , . . . , bn
n
X n
X n
X
(cak + bk ) = c ak + bk .
k=1 k=1 k=1

Proprietatea de liniaritate este verificat, de asemenea, i de seriile infinite convergente.


Proprietatea de liniaritate poate fi exploatat pentru a manipula sumele care ncorporeaz
notaii asimptotice. De exemplu,
n
n !
X X
(f (k)) = f (k) .
k=1 k=1

n aceast ecuaie, -notaia din membrul stng se aplic variabilei k, dar n membrul drept ea
se aplic lui n. Astfel de manipulri pot fi aplicate i seriilor infinite convergente.

Serii aritmetice
Suma
n
X
k = 1 + 2 + . . . + n,
k=1

care a aprut cnd am analizat sortarea prin inserie, este o serie aritmetic i are valoarea
n
X 1
k = n(n + 1) (3.1)
2
k=1
= (n2 ) (3.2)

Serii geometrice
Pentru orice x 6= 1 real, suma
n
X
xk = 1 + x + x2 + . . . + xn
k=0

este o serie geometric sau exponenial i are valoarea


n
X xn+1 1
xk = . (3.3)
x1
k=0

Cnd suma este infinit i |x| < 1 avem seria geometric infinit descresctoare

X 1
xk = . (3.4)
1x
k=0
3.1. Formule de nsumare i proprieti 39

Serii armonice
Pentru ntregi pozitivi n, al n-lea numr armonic este

X1 n
1 1 1 1
Hn = 1+ + + + ... + = = ln n + O(1). (3.5)
2 3 4 n k
k=1

Integrarea i diferenierea seriilor


Se pot obine formule suplimentare prin integrarea sau diferenierea formulelor de mai sus. De
exemplu, difereniind ambii membri ai seriei geometrice infinite (3.4) i nmulind cu x, obinem


X x
kxk = (3.6)
(1 x)2
k=0

Serii telescopante
Pentru orice ir a0 , a1 , . . . , an

n
X
(ak ak1 ) = an a0 (3.7)
k=1

deoarece fiecare dintre termenii a1 , a2 , . . . , an1 este adunat exact o dat i sczut exact o dat.
Spunem c suma telescopeaz. Analog,

n1
X
(ak ak+1 ) = a0 an .
k=0

Ca un exemplu de sum telescopant, s considerm seria

n1
X 1
.
k(k + 1)
k=1

Deoarece putem rescrie fiecare termen ca

1 1 1
= ,
k(k + 1) k k+1

obinem

n1
X 1 X 1
n1
1

1
= =1 .
k(k + 1) k k+1 n
k=1 k=1
40 Capitolul 3 Sume

Produse
Produsul finit a1 a2 an poate fi scris
n
Y
ak .
k=1

Dac n = 0, valoarea produsului este definit ca fiind 1. Putem converti o formul cu un produs
ntr-o formul cu o sum, utiliznd identitatea
n ! n
Y X
lg ak = lg ak .
k=1 k=1

Exerciii
Pn
3.1-1 Gsii o formul simpl pentru k=1 (2k 1).
Pn
3.1-2 ? Artai c k=1 1/(2k 1) = ln ( n) + O(1) manipulnd seria armonic.
P
3.1-3 ? Artai c k=0 (k 1)/2k = 0.
P
3.1-4 ? Evaluai suma k=1 (2k + 1)x2k .
Pn
Pn Utilizai proprietatea de liniaritate a nsumrii pentru a demonstra c k=1 O(fk (n)) =
3.1-5
O ( k=1 fk (n)).
P P
3.1-6 Demonstrai c k=1 (f (k)) = ( k=1 f (k)).
Qn
3.1-7 Evaluai produsul k=1 2 4k .
Qn
3.1-8 ? Evaluai produsul k=2 (1 1/k 2 ).

3.2. Delimitarea sumelor


Exist multe tehnici disponibile pentru delimitarea sumelor care descriu timpii de execuie
ai algoritmilor. Iat cteva dintre metodele cel mai frecvent utilizate.

Inducia matematic
Cea mai simpl cale de a evaluaPo serie este utilizarea induciei matematice. De exemplu,
n
s demonstrm c seria aritmetic k=1 k are valoarea 12 n(n + 1). Putem verifica uor pentru
n = 1, aa c facem ipoteza de inducie c formula este adevrat pentru orice n i demonstrm
c are loc pentru n + 1. Avem
n+1
X n
X 1 1
k= k + (n + 1) = n(n + 1) + (n + 1) = (n + 1)(n + 2).
2 2
k=1 k=1
3.2. Delimitarea sumelor 41

Nu trebuie s ghicim valoarea exact a unei sume pentru a utiliza inducia matematic.
Inducia poate fi P
utilizat i pentru a demonstra o delimitare. De exemplu,
Pn s demonstrm c
n
seria geometric k=0 3k este O(3n ). Mai precis, s demonstrm c k=0 3k c 3n pentru o
P0
anumit constant c. Pentru condiia iniial n = 0 avem k=0 3k = 1 c 1, ct timp c 1.
Presupunnd c delimitarea are loc pentru n, s demonstrm c are loc pentru n + 1. Avem
n+1
X n
X
k k n+1 n n+1 1 1
3 = 3 +3 c3 +3 = + c 3n+1 c 3n+1
3 c
k=0 k=0
Pn
ct timp (1/3 + 1/c) 1 sau, echivalent, c 3/2. Astfel, k=0 3k = O(3n ), ceea ce am dorit s
artm.
Trebuie s fim prudeni cnd utilizm notaii asimptotice pentru a demonstra
Pn delimitri prin
inducie. Considerm urmtoarea demonstraie vicioas a faptului c k=1 k = O(n). Desigur,
P1
k=1 k = O(1). Acceptnd delimitarea pentru n, o demonstrm acum pentru n + 1:

n+1
X n
X
k = k + (n + 1)
k=1 k=1
= O(n) + (n + 1) = greit!
= O(n + 1).

Greeala n argumentaie este aceea c O ascunde o constant care crete n funcie de n


i deci nu este constant. Nu am artat c aceeai constant e valabil pentru toi n.

Delimitarea termenilor
Uneori, o limit superioar bun a unei serii se poate obine delimitnd fiecare termen al
seriei, i este, de multe ori, suficient s utilizm cel mai mare termen pentru a-i delimita pe
ceilali. De exemplu, o limit superioar rapid a seriei aritmetice (3.1) este
n
X n
X
k n = n2 .
k=1 k=1
Pn
n general, pentru o serie k=1 ak , dac punem amax = max1kn ak , atunci
n
X
ak namax .
k=1

Tehnica delimitrii fiecrui termen dintr-o serie prin cel mai mare termen este o metod
Pn slab
cnd seria poate fi, n fapt, delimitat printr-o serie geometric. Fiind dat seria k=0 ak , s
presupunem c ak+1 /ak r pentru orice k 0, unde r < 1 este o constant. Suma poate fi
delimitat printr-o serie geometric descresctoare infinit, deoarece ak a0 rk , i astfel,
n
X
X
X 1
ak a0 r k = a0 r k = a0 .
1r
k=0 k=0 k=0
42 Capitolul 3 Sume

P k
Putem aplica aceast metod pentru a delimita suma k=1 (k/3 ). Primul termen este 1/3,
iar raportul termenilor consecutivi este
(k + 1)/3k+1 1 k+1 2
= ,
k/3k 3 k 3

pentru toi k 1. Astfel, fiecare termen este mrginit superior de (1/3)(2/3)k , astfel nct
X X k
k 1 2 1 1
k
= = 1.
3 3 3 3 1 2/3
k=1 k=1

O greeal banal n aplicarea acestei metode este s artm c raportul termenilor conse-
cutivi este mai mic dect 1 i apoi s presupunem c suma este mrginit de o serie geometric.
Un exemplu este seria armonic infinit, care diverge, deoarece

X n
X
1 1
= lim = lim (lg n) = .
k n k n
k=1 k=1

Raportul termenilor k + 1 i k n aceast serie este k/(k + 1) < 1, dar seria nu e mrginit
de o serie geometric descresctoare. Pentru a delimita o serie printr-o serie geometric, trebuie
s artm c raportul este mrginit de o constant subunitar; adic trebuie s existe un r < 1,
care este constant, astfel nct raportul tuturor perechilor de termeni consecutivi nu depete
niciodat r. n seria armonic nu exist nici un astfel de r, deoarece raportul devine arbitrar de
apropiat de 1.

Partiionarea sumelor
Delimitri pentru o sumare dificil se pot obine exprimnd seria ca o sum de dou sau mai
multe serii, partiionnd domeniul indicelui i apoi delimitnd fiecare dintre seriile rezultate.
De
Pn exemplu, s presupunem c ncercm s gsim o limit inferioar pentru seria aritmetic
2
k=1 k, despre care s-a artat deja c are limita superioar n . Am putea ncerca s minorm
fiecare termen al sumei prin cel mai mic termen, dar deoarece acest termen este 1, gsim o limit
inferioar de n pentru sum foarte departe de limita noastr superioar, n2 .
Putem obine o limit inferioar mai bun, partiionnd nti suma. S presupunem, pentru
comoditate, c n este par. Avem
n n/2 n n/2 n
X X X X X
k= k+ k 0+ (n/2) (n/2)2 = (n2 )
k=1 k=1 k=n/2+1 k=1 k=n/2+1
Pn
care este o limit asimptotic strns, deoarece k=1 k = O(n2 ).
Pentru o sum care apare din analiza unui algoritm, putem partiiona adesea suma i ignora
un numr constant de Pntermeni iniiali. n general, aceast tehnic se aplic atunci cnd fiecare
termen ak din suma k=0 ak este independent de n. Atunci pentru orice k0 > 0 constant putem
scrie
n
X kX
0 1 n
X n
X
ak = ak + ak = (1) + ak ,
k=0 k=0 k=k0 k=k0
3.2. Delimitarea sumelor 43

deoarece termenii iniiali ai sumei suntPtoi constani i numrul lor este constant. Apoi, putem
n
utiliza alte metode pentru a delimita k=k0 ak . De exemplu, pentru a gsi o limit superioar
asimptotic pentru

X k2
,
2k
k=0

observm c raportul termenilor consecutivi este


(k + 1)2 /2k+1 (k + 1)2 8
= ,
k 2 /2k 2k 2 9
dac k 3. Astfel, suma poate fi partiionat n
X X2 k
k2 k2 X k2 9X 8
= + O(1) + = O(1),
2k 2k 2k 8 9
k=0 k=0 k=3 k=0

deoarece a doua sum este o serie geometric descresctoare.


Tehnica partiionrii sumelor poate fi utilizat pentru a gsi delimitri asimptotice n situaii
mult mai dificile. De exemplu, putem obine o delimitare O(lg n) a seriei armonice (3.5)
n
X 1
Hn = .
k
k=1

Ideea este s partiionm domeniul de la 1 la n n blg nc pri i s delimitm superior


contribuia fiecrei pri prin 1. Astfel,
blg nc 2 1 i blg nc 2 1 i blg nc
n
X X X 1 X X 1 X
1
i
i
1 lg n + 1. (3.8)
k i=0 j=0
2 +j i=0 j=0
2 i=0
k=1

Aproximarea prin integrale


Pn
Cnd o sum poate fi exprimat ca k=m f (k), unde f (k) este o funcie monoton cresctoare,
o putem aproxima prin integrale:
Z n Xn Z n+1
f (x)dx f (k) f (x)dx. (3.9)
m1 k=m m

Justificarea pentru aceast aproximare este artat n figura 3.1. Suma este reprezentat prin
aria dreptunghiurilor din figur, iar integrala este regiunea haurat de sub curb. Cnd f (k)
este o funcie monoton descresctoare, putem utiliza o metod similar pentru a obine marginile
Z n+1 n
X Z n
f (x)dx f (k) f (x)dx (3.10)
m k=m m1

Aproximaia integral (3.10) d o estimare strns pentru al n-lea numr armonic. Pentru o
limit inferioar, obinem
Xn Z n+1
1 dx
= ln(n + 1). (3.11)
k 1 x
k=1
44 Capitolul 3 Sume

Pn
Figura 3.1 Aproximarea lui k=m f (k) prin integrale. Aria fiecrui dreptunghi este indicat n
interiorul dreptunghiului, iar aria tuturor dreptunghiurilor reprezint valoarea sumei. Integrala este
Rn
reprezentat prin aria haurat de sub curb. Comparnd ariile n (a), obinem m1 f (x)dx
Pn Pn
k=m f (k), i apoi, deplasnd dreptunghiurile cu o unitate la dreapta, obinem
R n+1 k=m f (k)

m
f (x)dx din (b).

Pentru limita superioar, deducem inegalitatea


n
X Z n
1 dx
= ln n,
k 1 x
k=2

care d limita
n
X 1
ln n + 1 (3.12)
k
k=1

Exerciii
Pn
3.2-1 Artai c k=1 1/k 2 este mrginit superior de o constant.
Probleme 45

3.2-2 Gsii o margine superioar a sumei


blg nc
X
dn/2k e.
k=0

3.2-3 Artai c al n-lea numr armonic este (lg n), partiionnd suma.
Pn
3.2-4 Aproximai k=1 k 3 printr-o integral.
Pn
3.2-5 De ce nu am utilizat aproximaia integral (3.10) direct pentru k=1 1/k pentru a obine
o margine superioar pentru al n-lea numr armonic?

Probleme
3-1 Delimitarea sumelor
Dai delimitri asimptotice strnse pentru urmtoarele sume. Presupunei c r 0 i s 0 sunt
constante.
n
X
a. kr .
k=1

n
X
b. lgs k.
k=1

n
X
c. k r lgs k.
k=1

Note bibliografice
Knuth [121] este o referin excelent pentru materialul prezentat n acest capitol. Proprieti
de baz ale seriilor pot fi gsite n orice carte bun de analiz, cum ar fi Apostol [12] sau Thomas
i Finney [192].
4 Recurene

Dup cum s-a observat n capitolul 1, cnd un algoritm conine o apelare recursiv la el
nsui, timpul su de execuie poate fi descris adesea printr-o recuren. O recuren este o
ecuaie sau o inegalitate care descrie o funcie exprimnd valoarea sa pentru argumente mai
mici. De exemplu, am vzut n capitolul 1 c timpul de execuie n cazul cel mai defavorabil
T (n) al procedurii Sorteaz-Prin-Interclasare poate fi descris prin recurena

(1) dac n = 1,
T (n) = (4.1)
2T (n/2) + (n) dac n > 1,
a crei soluie s-a afirmat c este T (n) = (n lg n).
Acest capitol ofer trei metode pentru rezolvarea recurenelor adic pentru obinerea unor
delimitri asimptotice sau O ale soluiei. n metoda substituiei, intuim o margine i
apoi utilizm inducia matematic pentru a demonstra c presupunerea noastr a fost corect.
Metoda iteraiei convertete recurena ntr-o sum i apoi se bazeaz pe tehnicile de delimitare
a sumelor pentru a rezolva recurena. Metoda master furnizeaz delimitri pentru recurene
de forma
T (n) = aT (n/b) + f (n),
unde a 1, b > 1, iar f (n) este o funcie dat; ea cere memorarea a trei cazuri, dar dup ce
facei asta, determinarea marginilor asimptotice pentru multe recurene simple este uoar.

Amnunte tehnice
n practic, neglijm anumite detalii tehnice cnd formulm i rezolvm recurene. Un bun
exemplu de detaliu care adesea este omis este presupunerea c funciile au argumente ntregi.
n mod normal, timpul de execuie T (n) al unui algoritm este definit numai cnd n este un
ntreg, deoarece pentru majoritatea algoritmilor, dimensiunea datelor de intrare este ntotdeauna
un ntreg. De exemplu, recurena care descrie timpul de execuie n cazul cel mai favorabil al
procedurii Sorteaz-Prin-Interclasare este, de fapt,

(1) dac n = 1,
T (n) = (4.2)
T (dn/2e) + T (bn/2c) + (n) dac n > 1.
Condiiile la limit reprezint o alt clas de detalii pe care, de obicei, le ignorm. Deoarece
timpul de execuie al unui algoritm pentru date de intrare de dimensiune constant este o
constant, recurenele care apar din timpii de execuie ai algoritmilor au, n general, T (n) = (1)
pentru n suficient de mic. n consecin, pentru comoditate, vom omite, n general, afirmaiile
despre condiiile la limit ale recurenelor i presupunem c T (n) este constant pentru n mic.
De exemplu, n mod normal formulm recurena (4.1) ca
T (n) = 2T (n/2) + (n), (4.3)
fr s dm n mod explicit valori mici pentru n. Motivul este c, dei schimbarea valorii lui
T (1) schimb soluia recurenei, soluia nu se modific, n mod obinuit, mai mult dect printr-un
factor constant, astfel c ordinul de cretere este neschimbat.
4.1. Metoda substituiei 47

Cnd formulm i rezolvm recurene, omitem, adesea prile ntregi inferioare i superioare
i condiiile la limit. Mergem nainte fr aceste detalii i apoi stabilim dac ele conteaz sau
nu. De obicei nu conteaz, dar este important s tim dac ele conteaz sau nu. Experiena ajut,
ajut i unele teoreme care afirm c aceste detalii nu afecteaz marginile asimptotice ale multor
recurene ntlnite n analiza algoritmilor (vezi teorema 4.1 i problema 4-5). n acest capitol,
totui, vom aborda cteva dintre aceste detalii pentru a arta unele dintre punctele sensibile ale
metodelor de rezolvare a recurenelor.

4.1. Metoda substituiei


Metoda substituiei pentru rezolvarea recurenelor presupune intuirea formei soluiei i apoi
utilizarea induciei matematice pentru a gsi constantele i a arta cum funcioneaz soluia.
Numele provine din substituirea rspunsului intuit pentru funcii cnd ipoteza induciei se aplic
pentru valori mai mici. Metoda este puternic dar ea poate fi aplicat, n mod evident, numai
n cazurile n care este uor de intuit forma soluiei.
Metoda substituiei poate fi utilizat pentru a stabili fie margini superioare, fie margini infe-
rioare pentru o recuren. De exemplu, s determinm o limit superioar pentru recurena

T (n) = 2T (bn/2c) + n (4.4)

care este similar cu recurenele (4.2) i (4.3). Intuim c soluia este T (n) = O(n lg n). Metoda
noastr const n a demonstra c T (n) cn lg n pentru o alegere corespunztoare a constantei
c > 0. ncepem prin a presupune c aceast delimitare este valabil pentru bn/2c, adic
T (bn/2c) cbn/2c lg(bn/2c). Substituind n recuren, se obine

T (n) 2(cbn/2c) lg(bn/2c)) + n cn lg(n/2) + n = cn lg n cn lg 2 + n


= cn lg n cn + n cn lg n,

unde ultimul pas este valabil ct timp c 1.


Inducia matematic ne cere acum s artm c soluia ndeplinete condiiile la limit.
Adic trebuie s artm c putem alege constanta c suficient de mare astfel nct delimitarea
T (n) cn lg n s funcioneze i pentru condiiile la limit. Aceast cerin conduce uneori la
probleme. S presupunem c T (1) = 1 este singura condiie la limit a recurenei. Atunci, din
nefericire, nu putem alege c suficient de mare, deoarece T (1) c1 lg 1 = 0.
Aceast dificultate n demonstrarea unei ipoteze de inducie pentru o condiie la limit
precis poate fi depit cu uurin. Profitm de faptul c notaia asimptotic ne cere doar s
demonstrm c T (n) > cn lg n pentru n n0 unde n0 este o constant. Ideea este s nlturm
din discuie condiia la limit dificil T (1) = 1 n demonstraia inductiv i s includem n = 2
i n = 3 ca parte a condiiilor la limit pentru demonstraie. Putem impune T (2) i T (3) ca i
condiii la limit pentru demonstraia inductiv, deoarece pentru n > 3, recurena nu se aplic
n mod direct lui T (1). Din recuren, deducem T (2) = 4 i T (3) = 5. Demonstraia inductiv c
T (n) cn lg n pentru o anumit constant c 1 poate fi completat acum, alegnd c suficient de
mare pentru ca T (2) c2 lg 2 i T (3) c3 lg 3. Dup cum se dovedete, orice alegere a lui c 2
este suficient. Pentru majoritatea recurenelor pe care le vom examina, extensia condiiilor la
limit pentru a face ipoteza de inducie s funcioneze pentru valori mici ale lui n este imediat.
48 Capitolul 4 Recurene

Realizarea unei aproximri bune


Din nefericire, nu exist o metod general de intuire a soluiilor corecte ale unei recurene.
Intuirea unei soluii necesit experien i, ocazional, creativitate. Din fericire, totui, exist o
anumit euristic care poate ajuta.
Dac o recuren este similar cu una pe care ai vzut-o deja, intuirea unei soluii similare
este rezonabil. Ca exemplu, s considerm recurena

T (n) = 2T (bn/2c) + 17) + n,

care pare adevrat datorit adugrii lui 17 n argumentul lui T n membrul drept. Intuitiv,
totui, acest termen suplimentar nu poate afecta n mod substanial soluia recurenei. Cnd n
este mare, diferena dintre T (bn/2c) i T (bn/2c + 17) nu e att de mare: ambele l taie pe n
aproximativ n dou. n consecin, intuim c T (n) = O(n lg n), relaie a crei corectitudine se
poate verifica utiliznd metoda substituiei (vezi exerciiul 4.1-5).
Alt cale de a face o intuire bun este s demonstrm limite superioare i inferioare largi ale
recurenei i apoi s reducem incertitudinea. De exemplu, putem ncepe cu o limit inferioar
T (n) = (n) pentru recurena (4.4), deoarece avem termenul n n recuren i putem demonstra
o limit superioar iniial T (n) = O(n2 ). Apoi, putem cobor gradual limita superioar i ridica
limita inferioar pn cnd ajungem la soluia corect, asimptotic strns, T (n) = (n lg n).

Subtiliti
Exist ocazii cnd putei intui corect o delimitare asimptotic a soluiei unei recurene, dar,
cumva, matematica nu pare s funcioneze n inducie. De regul, problema este c ipoteza de
inducie nu este suficient de tare pentru a demonstra delimitarea detaliat. Cnd ajungei ntr-
un astfel de impas, revizuirea aproximrii prin scoaterea unui termen de ordin mai mic permite,
adesea, matematicii s funcioneze.
S considerm recurena

T (n) = T (bn/2c) + T (dn/2e) + 1.

Intuim c soluia este O(n) i ncercm s artm c T (n) cn pentru o alegere


corespunztoare a constantei c. Substituind presupunerea noastr n recuren, obinem

T (n) cbn/2c + cdn/2e + 1 = cn + 1,

care nu implic T (n) cn pentru orice alegere a lui c. Este tentant s ncercm o soluie mai
mare, s zicem T (n) = O(n2 ), care poate fi fcut s funcioneze dar, n fapt, aproximarea
noastr c soluia este T (n) = O(n) este corect. Pentru a demonstra aceasta, totui, trebuie s
facem o ipotez de inducie mai tare.
La prima vedere, aproximarea noastr e aproape corect: avem n plus doar constanta 1, un
termen de ordin inferior. Totui, inducia matematic nu funcioneaz dect dac demonstrm
forma exact a ipotezei de inducie. Depim aceast dificultate scznd un termen de ordin
inferior din aproximarea noastr precedent. Noua noastr intuire este T (n) cn b, unde
b 0 este constant. Avem acum

T (n) (cbn/2c b) + (cdn/2e b) + 1 = cn 2b + 1 cn b,


4.1. Metoda substituiei 49

ct timp b 1. Ca i mai nainte, constanta c trebuie s fie aleas suficient de mare, pentru a
ndeplini condiiile la limit.
Majoritatea oamenilor gsesc ideea scderii unui termen de ordin inferior contraintuitiv. La
urma urmei, dac matematica nu funcioneaz, n-ar trebui s mrim soluia intuit? Cheia n
ntelegerea acestui pas este s ne amintim c utilizm inducia matematic: putem demonstra o
proprietate mai puternic pentru o valoare dat acceptnd o proprietate adevrat pentru valori
mai mici.

Evitarea capcanelor
Este uor s greim n utilizarea notaiei asimptotice. De exemplu, n recurena (4.4) putem
demonstra n mod greit c T (n) = O(n) presupunnd c T (n) cn i apoi argumentnd c

T (n) 2(cbn/2c) + n cn + n
= O(n), = greit!!

deoarece c este o constant. Eroarea este c nu am demonstrat forma exact a ipotezei de


inducie, adic faptul c T (n) cn.

Schimbarea variabilelor
Uneori, o mic manipulare algebric poate s transforme o recuren necunoscut ntr-una
similar cunoscut. De exemplu, s considerm recurena

T (n) = 2T (b nc) + lg n,

care pare dificil. Putem simplifica aceast recuren, totui, printr-o schimbare de variabile.
Pentru comoditate, nu ne vom face griji n ceea ce privete rotunjirea valorilor, astfel nct ele
s fie ntregi, cum e cazul cu n. Redenumind m = lg n, obinem

T (2m ) = 2T (2m/2 ) + m.

Putem redenumi acum S(m) = T (2n ) pentru a obine nou recuren

S(m) = 2S(m/2) + m,

care e foarte asemntoare cu recurena (4.4) i are aceeai soluie: S(m) = O(m lg n). Revenind
de la S(m) la T (n), obinem T (n) = T (2m ) = S(m) = O(m lg m) = O(lg n lg lg n).

Exerciii
4.1-1 Artai c soluia lui T (n) = T (dn/2e) + 1 este O(lg n).

4.1-2 Artai c soluia lui T (n) = 2T (bn/2c) + n este (n lg n). Concluzionai c soluia este
(n lg n).

4.1-3 Artai c fcnd o ipotez de inducie diferit, putem depi dificultatea cu condiia la
limit T (1) = 1 pentru recurena (4.4) fr a ajusta condiiile la limit pentru demonstraia
inductiv.
50 Capitolul 4 Recurene

4.1-4 Artai c (n lg n) este soluia recurenei exacte (4.2) pentru procedura Sorteaz-
Prin-Interclasare.

4.1-5 Artai c soluia lui T (n) = 2T (bn/2c + 17) + n este O(n lg n).

4.1-6 Rezolvai recurena T (n) = 2T ( n) + 1 fcnd o schimbare de variabile, indiferent dac
valorile sunt ntregi sau nu.

4.2. Metoda iteraiei


Metoda iterrii unei recurene nu ne cere s aproximm o soluie dar poate necesita mai
multe noiuni de algebr dect metoda substituiei. Ideea este s dezvoltm (iterm) recurena
i s o exprimm ca o sum de termeni care depind numai de n i de condiiile iniiale. Se pot
utiliza apoi tehnici de evaluare a sumelor pentru a gsi delimitri ale soluiei.
De exemplu, s considerm recurena
T (n) = 3T (bn/4c) + n.
O iterm dup cum urmeaz:
T (n) = n + 3T (bn/4c) = n + 3(bn/4c + 3T (bn/16c))
= n + 3(bn/4c + 3(bn/16c + 3T (bn/64c)))
= n + 3bn/4c + 9bn/16c + 27T (bn/64c),
unde bbn/4c/4c = bn/16c i bbn/16c/4c = bn/64c rezult din identitatea (2.4).
Ct de departe trebuie s iterm recurena pentru a ajunge la condiia limit? Cel de-al i-lea
termen din serie este 3i bn/4i c. Iteraia ajunge la n = 1 cnd bn/4i c = 1 sau, echivalent, cnd i
depete log4 n.
Continund iterarea pn n acest punct i utiliznd delimitarea bn/4i c n/4i , descoperim
c suma conine o serie geometric descresctoare:
T (n) n + 3n/4 + 9n/16 + 27n/64 + . . . + 3log4 n (1)
X i
3 3
n + nlog4 = 4n + o(n) = O(n).
i=0
4

Aici, am utilizat identitatea (2.9) pentru a concluziona c 3log4 n = nlog4 3 i am utilizat faptul
c log4 3 < 1 pentru a deduce c (nlog4 3 ) = o(n).
Metoda iteraiei duce de obicei la multe noiuni de algebr, iar asigurarea corectitudinii
calculelor poate fi o problem. Cheia este s ne focalizm asupra a doi parametri: numrul de
recurene necesare pentru a ajunge la condiia la limit i suma termenilor care apar la fiecare
nivel al procesului de iteraie. Uneori, n procesul de iterare a unei recurene, putei intui soluia
fr a face toate calculele. Atunci iterarea poate fi abandonat n favoarea metodei substituiei,
care de regul necesit mai puine noiuni de algebr.
Cnd o recuren conine funciile parte ntreag inferioar i superioar, calculele pot deveni
deosebit de complicate. Adesea este util s presupunem c recurena este definit numai pe
puterile exacte ale unui numr. n exemplul nostru, dac am fi presupus c n = 4k pentru un
4.2. Metoda iteraiei 51

anumit ntreg k, funcia parte ntreag inferioar ar fi putut fi omis, n mod convenabil. Din
nefericire, demonstrarea delimitrii T (n) = O(n) numai pentru puterile exacte ale lui 4 este,
din punct de vedere tehnic, un abuz al notaiei O. Definiiile notaiei asimptotice pretind ca
delimitrile s fie demonstrate pentru toi ntregii suficient de mari, nu doar pentru acei care
sunt puteri ale lui 4. Vom vedea n seciunea 4.3 c pentru un mare numr de recurene aceast
dificultate tehnic poate fi depit. Problema 4-5 ofer, de asemenea, condiii n care o analiz
pentru puterile exacte ale unui ntreg poate fi extins la toi ntregii.

Arbori de recuren
Un arbore de recuren este un mod convenabil de a vizualiza ceea ce se ntmpl cnd o
recuren este iterat i poate s ajute la organizarea aparatului algebric necesar pentru a rezolva
recurena. Este n mod special util cnd recurena descrie un algoritm divide i stpnete. Figura
4.1 arat deducerea arborelui de recuren pentru

T (n) = 2T (n/2) + n2 .

Pentru comoditate, presupunem c n este o putere exact a lui 2. Partea (a) a figurii arat
T (n), care n partea (b) a fost dezvoltat ntr-un arbore echivalent care reprezint recurena.
Termenul n2 este rdcina (costul la nivelul cel mai de sus al recurenei), iar cei doi subarbori
ai rdcinii sunt cele dou recurene mai mici T (n/2). Partea (c) arat acest proces dus cu un
pas mai departe, dezvoltnd T (n/2). Costul pentru fiecare dintre cele dou subnoduri de la al
doilea nivel al recurenei este (n/2)2 . Continum dezvoltarea fiecrui nod din arbore, sprgndu-l
n prile componente, aa cum sunt determinate de recuren, pn ajungem la o condiie la
limit. Partea (d) arat arborele obinut.
Evalum acum recurena adunnd valorile de la fiecare nivel al arborelui. Nivelul cel mai
nalt are valoarea total n2 , nivelul al doilea are valoarea (n/2)2 + (n/2)2 = n2 /2, al treilea nivel
are valoarea (n/4)2 + (n/4)2 + (n/4)2 + (n/4)2 = n2 /4 i aa mai departe. Deoarece valorile
descresc geometric, totalul este cu cel mult un factor constant mai mare dect termenul cel mai
mare (primul) i deci soluia este (n2 ).
Cu un alt exemplu, mai complicat, figura 4.2 arat arborele de recuren pentru

T (n) = T (n/3) + T (2n/3) + n.

(Pentru simplitate, omitem iari funciile parte ntreag inferioar i superioar). Cnd
adugm valorile de la nivelurile arborelui de recuren, obinem o valoare a lui n pentru fiecare
nivel. Cel mai lung drum de la rdcin la o frunz este n (2/3)n (2/3)2 n . . .
1. Deoarece (2/3)k n = 1 cnd k = log3/2 n, nlimea arborelui este log3/2 n. Astfel, soluia
recurenei este cel mult n log3/2 n = O(n lg n).

Exerciii
4.2-1 Determinai o limit superioar asimptotic bun pentru recurena T (n) = 3T (bn/2c)+n
prin iteraie.

4.2-2 Argumentai c soluia recurenei T (n) = T (n/3) + T (2n/3) + n este (n lg n) fcnd


apel la un arbore de recuren.
52 Capitolul 4 Recurene

Figura 4.1 Construirea arborelui de recuren pentru T (n) = 2T (n/2) + n2 . Partea (a) l prezint pe
T (n) care n (b)-(d) este expandat treptat n trei arbori de recuren. Arborele expandat complet din
partea (d) are nlimea lg n (are lg n + 1 niveluri).

4.2-3 Determinai arborele de recuren pentru T (n) = 4T (bn/2c) + n i dai margini


asimptotice strnse pentru soluia sa.

4.2-4 Utilizai iteraia pentru a rezolva recurena T (n) = T (n a) + T (a) + n, unde a 1 este
o constant.

4.2-5 Utilizai un arbore de recuren pentru a rezolva recurena T (n) = T (n)+T ((1)n)+n,
unde este o constant din domeniul 0 < < 1.
4.3. Metoda master 53

Figura 4.2 Un arbore de recuren pentru T (n) = T (n/3) + T (2n/3) + n.

4.3. Metoda master


Metoda master furnizeaz o reet pentru rezolvarea recurenelor de forma

T (n) = aT (n/b) + f (n) (4.5)

unde a 1 i b > 1 sunt constante, iar f (n) este o funcie asimptotic pozitiv. Metoda master
pretinde memorarea a trei cazuri, dar apoi soluia multor recurene se poate determina destul
de uor, de multe ori fr creion i hrtie.
Recurena (4.5) descrie timpul de execuie al unui algoritm care mparte o problem de di-
mensiune n n a subprobleme, fiecare de dimensiune n/b, unde a i b sunt constante pozitive.
Cele a subprobleme sunt rezolvate recursiv, fiecare n timp T (n/b). Costul divizrii problemei i
al combinrii rezultatelor subproblemelor este descris de funcia f (n). (Adic, utiliznd notaia
din seciunea 1.3.2, f (n) = D(n) + C(n).) De exemplu, n recurena din procedura Sorteaz-
Prin-Interclasare a = 2, b = 2 i f (n) = (n).
Din punctul de vedere al corectitudinii tehnice, recurena nu este, de fapt, bine definit,
deoarece n/b ar putea s nu fie un ntreg. nlocuirea fiecruia dintre cei a termeni T (n/b) fie cu
T (bn/bc) fie cu T (dn/be) nu afecteaz, totui, comportamentul asimptotic al recurenei. (Vom
demonstra aceasta n seciunea urmtoare.) n mod normal ne va conveni, de aceea, s omitem
funciile parte ntreag inferioar i superioar cnd scriem recurene divide i stpnete de
aceast form.

Teorema master
Metoda master depinde de urmtoarea teorem.
54 Capitolul 4 Recurene

Teorema 4.1 (Teorema master) Fie a 1 i b > 1 constante, fie f (n) o funcie i fie T (n)
definit pe ntregii nenegativi prin recurena
T (n) = aT (n/b) + f (n)
unde interpretm n/b fie ca bn/bc, fie ca dn/be. Atunci T (n) poate fi delimitat asimptotic dup
cum urmeaz.

1. Dac f (n) = O(nlogb a ) pentru o anumit constant > 0, atunci T (n) = (nlogb a ).
2. Dac f (n) = (nlogb a ), atunci T (n) = (nlogb a lg n).
3. Dac f (n) = (nlogb a+ ) pentru o anumit constant > 0, i dac af (n/b) cf (n)
pentru o anumit constant c < 1 i toi n suficient de mari, atunci T (n) = (f (n)).

nainte de a aplica teorema master la cteva exemple, s ne oprim puin ca s nelegem ce


spune. n fiecare dintre cele trei cazuri, comparm funcia f (n) cu funcia nlogb a . Intuitiv, soluia
recurenei este determinat de cea mai mare dintre cele dou funcii. Dac funcia nlogb a este
mai mare, ca n cazul 1, atunci soluia este T (n) = (nlogb a ). Dac funcia f (n) este mai mare,
ca n cazul 3, atunci soluia este T (n) = (f (n)). Dac cele dou funcii sunt de acelai ordin de
mrime, ca n cazul 2, nmulim cu un factor logaritmic, iar soluia este T (n) = (nlogb a lg n) =
(f (n) lg n).
Dincolo de aceast intuiie, exist nite detalii tehnice care trebuie nelese. n primul caz,
f (n) trebuie nu numai s fie mai mic dect nlogb a , trebuie s fie polinomial mai mic. Adic f (n)
trebuie s fie asimptotic mai mic dect nlogb a cu un factor n pentru o anumit constant > 0.
n al treilea caz, f (n) trebuie nu numai s fie mai mare dect nlogb a , trebuie s fie polinomial
mai mare i, n plus, s verifice condiia de regularitate af (n/b) cf (n). Aceast condiie este
satisfcut de majoritatea funciilor polinomial mrginite pe care le vom ntlni.
Este important de realizat c cele trei cazuri nu acoper toate posibilitile pentru f (n).
Exist un gol ntre cazurile 1 i 2 cnd f (n) este mai mic dect nlogb a , dar nu polinomial mai
mic. Analog, exist un gol ntre cazurile 2 i 3, cnd f (n) este mai mare dect blogb a dar nu
polinomial mai mare. Dac funcia f (n) cade ntr-unul dintre aceste goluri, sau cnd a condiia
de regularitate din cazul 3 nu este verificat, metoda master nu poate fi utilizat pentru a rezolva
recurena.

Utilizarea metodei master


Pentru a utiliza metoda master, stabilim pur i simplu care caz al teoremei se aplic (dac e
vreunul) i scriem soluia.
Ca un prim exemplu, s considerm
T (n) = 9T (n/3) + n.
Pentru aceast recuren, avem a = 9, b = 3, f (n) = n i astfel nlogb a = nlog3 9 = (n2 ).
Deoarece f (n) = O(nlog3 9 ), unde = 1, putem s aplicm cazul 1 al teoremei master i s
considerm c soluia este T (n) = (n2 ).
S considerm acum
T (n) = T (2n/3) + 1,
4.4. Demonstraia teoremei master 55

n care a = 1, b = 3/2, f (n) = 1 i nlogb a = nlog3/2 1 = n0 = 1. Cazul 2 este cel care se aplic,
deoarece f (n) = (nlogb a ) = (1) i astfel soluia recurenei este T (n) = (lg n).
Pentru recurena

T (n) = 3T (n/4) + n lg n,

avem a = 3, b = 4, f (n) = n lg n i nlogb a = nlog4 3 = O(n0.793 ). Deoarece f (n) = (nlog4 3+ ),


unde 0.2, cazul 3 se aplic dac putem arta c pentru f (n) este verificat condiia de
regularitate. Pentru n suficient de mare, af (n/b) = 3(n/4) lg(n/4) (3/4)n lg n = cf (n) pentru
c = 3/4. n consecin, din cazul 3, soluia recurenei este T (n) = (n lg n).
Metoda master nu se aplic recurenei

T (n) = 2T (n/2) + n lg n,

chiar dac are forma potrivit: a = 2, b = 2, f (n) = n lg n i nlgb a = n. Se pare c ar trebui


s se aplice cazul 3, deoarece f (n) = n lg n este asimptotic mai mare dect nlogb a = n, dar nu
polinomial mai mare. Raportul f (n)/nlogb a = (n lg n)/n = lg n este asimptotic mai mic dect n
pentru orice constant pozitiv . n consecin, recurena cade n golul dintre cazurile 2 i 3.
(Soluia este dat n exerciiul 4.4-2).

Exerciii
4.3-1 Utilizai metoda master pentru a da o delimitare asimptotic strns pentru urmtoarele
recurene.

a. T (n) = 4T (n/2) + n.

b. T (n) = 4T (n/2) + n2 .

c. T (n) = 4T (n/2) + n3 .

4.3-2 Timpul de execuie al unui algoritm A este descris prin recurena T (n) = 7T (n/2) + n2 .
Un algoritm concurent A0 are timpul de execuie de T 0 = aT 0 (n/4) + n2 . Care este cea mai mare
valoare ntreag a lui a astfel nct A0 este asimptotic mai rapid dect A?

4.3-3 Utilizai metoda master pentru a arta c soluia recurenei T (n) = T (n/2) + (1) a
cutrii binare (vezi exerciiul 1.3-5) este T (n) = (lg n).

4.3-4 ? Considerm condiia de regularitate af (n/b) cf (n) pentru o anumit constant c < 1,
care face parte din cazul 3 al teoremei master. Dai un exemplu de o funcie simpl f (n) care
satisface toate condiiile din cazul 3 al teoremei master, cu excepia condiiei de regularitate.

4.4. Demonstraia teoremei master


Aceast seciune conine o demonstraie a teoremei master (teorema 4.1) pentru cititorii
avnd cunotine mai avansate. Pentru a aplica teorema nu este nevoie de nelegerea demon-
straiei.
56 Capitolul 4 Recurene

Demonstraia const din dou pri. Prima parte analizeaz recurena master (4.5) n
ipoteza simplificatoare c T (n) este definit numai pe puterile exacte ale lui b > 1, adic pentru
n = 1, b, b2 , . . . Aceast parte furnizeaz toat intuiia necesar pentru a nelege de ce teorema
master este adevrat. A doua parte arat de ce analiza se poate extinde la toi ntregii pozitivi
n i este, n esen, tehnic matematic aplicat la problema tratrii prilor ntregi inferioare
i superioare.
n aceast seciune, uneori vom abuza uor de notaia noastr asimptotic, utiliznd-o pentru
a descrie funcii care sunt definite numai pe puteri exacte ale lui b. Reamintim c definiiile
notaiilor asimptotice pretind ca delimitrile s fie demonstrate pentru toate numerele suficient
de mari, nu numai pentru cele care sunt puteri ale lui b. Deoarece am putea introduce noi notaii
asimptotice care s se aplice mulimii {bi : i = 0, 1, . . .} n locul ntregilor nenegativi, acest abuz
este minor.
Oricum, trebuie s fim ntotdeauna pui n gard cnd utilizm notaii asimptotice pe un
domeniu limitat, ca s nu tragem concluzii improprii. De exemplu, demonstrarea faptului c
T (n) = O(n) cnd n este o putere exact a lui 2 nu garanteaz c T (n) = O(n). Funcia T (n)
poate fi definit ca

n dac n = 1, 2, 4, 8, . . . ,
T (n) =
n2 n rest,

caz n care cea mai bun margine superioar ce poate fi demonstrat este T (n) = O(n2 ). Din
cauza acestui gen de consecine drastice, niciodat nu vom utiliza notaia asimptotic pe un
domeniu limitat fr s atragem atenia asupra acestui lucru.

4.4.1. Demonstraia pentru puteri exacte


Prima parte a demonstraiei teoremei master analizeaz recurena master (4.5),

T (n) = aT (n/b) + f (n),

n ipoteza c n este o putere exact a lui b > 1, unde n nu trebuie s fie un ntreg. Analiza e
mprit n trei leme. Prima reduce problema rezolvrii recurenei master la problema evalurii
unei expresii care conine o sum. A doua determin margini ale acestei sume. A treia lem le
pune mpreun pe primele dou pentru a demonstra o versiune a teoremei master pentru cazul
n care n este o putere exact a lui b.

Lema 4.2 Fie a 1 i b > 1 constante i fie f (n) o funcie nenegativ definit pe puterile
exacte ale lui b. Definim T (n) pe puterile exacte ale lui b prin recurena

(1) dac n = 1,
T (n) =
aT (n/b) + f (n) dac n = bi ,

unde i este un ntreg pozitiv. Atunci


logb n1
X
T (n) = (nlogb a ) + aj f (n/bj ). (4.6)
j=0
4.4. Demonstraia teoremei master 57

Demonstraie. Iterarea recurenei conduce la

T (n) = f (n) + aT (n/b) = f (n) + af (n/b) + a2 T (n/b2 )


= f (n) + af (n/b) + a2 f (n/b2 ) + . . . + alogb n1 f (n/blogb n1 ) + alogb n T (1).

Deoarece alogb n = nlogb a , ultimul termen al acestei expresii devine

alogb n T (1) = (nlogb a ),

utiliznd condiia la limit T (1) = (1). Termenii rmai pot fi exprimai sub forma sumei
logb n1
X
aj f (n/bj );
j=0

astfel,
logb n1
X
logb a
T (n) = (n )+ aj f (n/bj ),
j=0

ceea ce completeaz demonstraia.

Arborele de recuren
nainte de a continua, vom ncerca s intuim puin demonstraia utiliznd un arbore de
recuren. Figura 4.3 arat arborele corespunztor iterrii recurenei din lema 4.2. Rdcina
arborelui are costul f (n) i are a fii, fiecare cu costul f (n/b). (Este convenabil s ne gndim la
a ca fiind un ntreg, n special cnd vizualizm arborele de recuren, dar din punct de vedere
matematic nu este necesar acest lucru.) Fiecare dintre fii are a fii cu costul f (n/b2 ) i astfel exist
a2 noduri situate la distana 2 de rdcin. n general, exist aj noduri care sunt la distana
j de rdcin i fiecare are costul f (n/bj ). Costul fiecrei frunze este T (1) = (1) i fiecare
frunz este la distana logb n de rdcin, deoarece n/blogb n = 1. Exist nlogb n = nlogb a frunze
n arbore.
Putem obine ecuaia (4.6) nsumnd costurile fiecrui nivel al arborelui, dup cum se arat
n figur. Costul pentru un nivel j de noduri interne este aj f (n/bj ) i astfel totalul pe toate
nivelurile de noduri interne este
logb n1
X
aj f (n/bj ).
j=0

n algoritmul divide i stpnete prezentat, aceast sum reprezint costurile divizrii pro-
blemelor n subprobleme i apoi al recombinrii subproblemelor. Costul tuturor frunzelor, care
este costul rezolvrii tuturor celor nlogb a subprobleme de dimensiune 1, este (nlogb a ).
n limbajul arborelui de recuren, cele trei cazuri ale teoremei master corespund cazurilor n
care costul total al arborelui este (1) dominat de costul frunzelor, (2) egal distribuit pe nivelurile
arborelui sau (3) dominat de costul rdcinii.
Suma din ecuaia (4.6) descrie costul pailor de divizare i combinare din algoritmul divide i
stpnete prezentat. Urmtoarea lem furnizeaz delimitri asimptotice asupra creterii sumei.
58 Capitolul 4 Recurene

Figura 4.3 Arborele de recuren generat de T (n) = aT (n/b) + f (n). Acesta este un arbore complet a-
ar cu nlogb a frunze, avnd nlimea logb n. Costul fiecrui nivel este notat n dreapta, iar suma acestora
este dat de ecuaia (4.6)

Lema 4.3 Fie a 1 i b > 1 constante i fie f (n) o funcie nenegativ definit pe puterile
exacte ale lui b. O funcie definit pe puterile exacte ale lui b prin

logb n1
X
g(n) = aj f (n/bj ) (4.7)
j=0

poate fi delimitat asimptotic pentru puterile exacte ale lui b dup cum urmeaz.

1. Dac f (n) = O(nlogb a ) pentru o constant > 0, atunci g(n) = O(nlogb a ).

2. Dac f (n) = (nlogb a ), atunci g(n) = (nlogb a lg n).

3. Dac af (n/b) cf (n) pentru o anumit constant c < 1 i toi n b, atunci g(n) =
(f (n)).

Demonstraie. Pentru cazul 1, avem f (n) = O(nlogb a ), de unde f (n/bj ) = O((n/bj )logb a ).
nlocuind n ecuaia (4.7) rezult

logb n1
X n logb a
g(n) = O aj . (4.8)
j=0
bj
4.4. Demonstraia teoremei master 59

Delimitm suma din interiorul O-notaiei factoriznd termenii i simplificnd, rezultnd o


serie geometric cresctoare
logb n1 n logb a logb n1 j logb n1
X X ab X
j logb a logb a
a = n =n (b )j
j=0
bj j=0
blogb a j=0
log n
logb a b b 1 logb a n 1
= n =n .
b 1 b 1

Deoarece b i sunt constante, ultima expresie se reduce la nlogb a O(n ) = O(nlogb a ).


nlocuind aceast expresie n suma din ecuaia (4.8), obinem

g(n) = O nlogb a ,

i cazul 1 este demonstrat.


n ipoteza c f (n) = (nlogb a ) pentru cazul 2, avem f (n/bj ) = ((n/bj )logb a ). nlocuind n
ecuaia (4.7) rezult

logb n1
X n logb a
g(n) = aj j (4.9)
j=0
b

Delimitm suma din interiorul lui ca i n cazul 1, dar de data aceasta nu obinem o serie
geometric. n schimb, descoperim c fiecare termen al sumei este acelai
logb n1
X n logb a logb n1
X a j logb n1
X
aj = nlogb a = nlogb a 1 = nlogb a logb n.
j=0
bj j=0
blogb a j=0

nlocuind aceast expresie pentru sum n ecuaia (4.9) rezult

g(n) = (nlogb a logb n) = (nlogb a lg n),

i cazul 2 este demonstrat.


Cazul 3 se demonstreaz similar. Deoarece f (n) apare n definiia (4.7) a lui g(n) i toi
termenii lui g(n) sunt nenegativi, putem concluziona c g(n) = (f (n)) pentru puterile exacte
ale lui b. n ipoteza c af (n/b) cf (n) pentru o anumit constant c < 1 i toi n b, avem
aj f (n/bj ) cj f (n).
Substituind n ecuaia (4.7) i simplificnd, rezult o serie geometric, dar spre deosebire de
seria din cazul 1, aceasta are termeni descresctori
logb n1 logb n1
X X X 1
g(n) aj f (n/bj ) cj f (n) f (n) cj = f (n) = O(f (n)),
j=0 j=0 j=0
1c

deoarece c este o constant. Astfel, putem concluziona c g(n) = (f (n)) pentru puterile exacte
ale lui b. Cazul 3 este demonstrat, ceea ce completeaz demonstraia lemei.
Putem demonstra acum o versiune a teoremei master pentru cazul n care n este o putere
exact a lui b.
60 Capitolul 4 Recurene

Lema 4.4 Fie a 1 i b > 1 constante i fie f (n) o funcie nenegativ, definit pe puterile
exacte ale lui b. Definim T (n) pe puterile exacte ale lui b prin recurena

(1) dac n = 1,
T (n) =
aT (n/b) + f (n) dac n = bi ,

unde i este un ntreg pozitiv. Atunci T (n) poate fi delimitat asimptotic pentru puterile exacte
ale lui b dup cum urmeaz

1. Dac f (n) = O(nlogb a ) pentru o anumit constant > 0, atunci T (n) = (nlogb a ).

2. Dac f (n) = (nlogb a ), atunci T (n) = (nlogb a lg n).

3. Dac f (n) = (nlogb a+ ) pentru o anumit constant > 0 i dac af (n/b) cf (n) pentru
o anumit constant c < 1 i toate valorile lui n suficient de mari, atunci T (n) = (f (n)).

Demonstraie. Utilizm delimitrile din lema 4.3 pentru a evalua suma (4.6) din lema 4.2.
Pentru cazul 1, avem

T (n) = (nlogb a ) + O(nlogb a ) = (nlogb a ),

iar pentru cazul 2,

T (n) = (nlogb a ) + (nlogb a lg n) = (nlogb a lg n).

Pentru cazul 3, condiia af (n/b) cf (n) implic f (n) = (nlogb a+ ) (vezi exerciiul 4.4-3).
n consecin,

T (n) = (nlogb a ) + (f (n)) = (f (n)).

Cu aceasta lema este demonstrat.

4.4.2. Pri ntregi inferioare i superioare


Pentru a demonstra teorema master, trebuie s extindem acum analiza noastr la situaia n
care n recurena master sunt utilizate pri ntregi inferioare i superioare, astfel c recurena
este definit pentru orice numere ntregi, nu doar pentru puterile exacte ale lui b. Obinerea unei
margini inferioare pentru

T (n) = aT (dn/be) + f (n) (4.10)

i a unei margini superioare pentru

T (n) = aT (bn/bc) + f (n) (4.11)

este o operaie de rutin, deoarece delimitarea dn/be nb poate fi utilizat n primul caz pentru a
obine rezultatul dorit, iar delimitarea bn/bc n/b poate fi utilizat n al doilea caz. Delimitarea
inferioar a recurenei (4.11) necesit n mare parte acelai procedeu ca i delimitarea superioar
a recurenei (4.10), astfel c vom prezenta numai ultima delimitare.
4.4. Demonstraia teoremei master 61

Vrem s iterm recurena (4.10) aa cum s-a fcut n lema 4.2. Pe msur ce iterm recurena,
obinem un ir de invocri recursive cu argumentele
n, dn/be,
ddn/be/be,
dddn/be/be/be,
..
.
S notm al i-lea element din ir cu ni , unde

n dac i = 0,
ni = (4.12)
dni1 /be dac i > 0.
Primul nostru scop este s determinm numrul k de iteraii astfel nct nk s fie o constant.
Utiliznd inegalitatea dxe x + 1, obinem
n0 n,
n1 nb + 1,
n2 bn2 + 1b + 1,
n3 bn3 + b12 + 1b + 1,
..
.

n general,
i1
n X 1 n b
ni + i+ ,
bi j=0 bj b b1

i astfel, cnd i = blogb nc, obinem ni b + b/(b 1) = O(1).


Putem itera acum recurena (4.10), obinnd
T (n) = f (n0 ) + aT (n1 ) = f (n0 ) + af (n1 ) + a2 T (n2 )
f (n0 ) + af (n1 ) + a2 f (n2 ) + . . . + ablogb nc1 f (nblogb nc1 ) + ablogb nc T (nblogb nc )
blogb nc1
X
logb a
= (n )+ aj g(nj ) (4.13)
j=0

care este foarte asemntoare cu ecuaia (4.6) cu excepia faptului c n este un ntreg arbitrar
i nu e restrns la o putere exact a lui b.
Putem evalua acum suma
blogb nc1
X
g(n) = aj f (nj ) (4.14)
j=0

din (4.13) ntr-o manier similar cu demonstraiei lemei 4.3. ncepnd cu cazul 3, dac
af (dn/be) cf (n) pentru n > b + b/(b 1), unde c < 1 este o constant, atunci rezult c
aj f (nj ) cj f (n). De aceea, suma din ecuaia (4.14) poate fi evaluat exact ca n lema 4.3. Pentru
cazul 2, avem f (n) = (nlogb a ). Dac putem arta c f (nj ) = O(nlogb a /aj ) = O((n/bj )logb a ),
atunci demonstraia este valabil i n acest caz. Observm c j blogb nc implic bj /n 1.
62 Capitolul 4 Recurene

Delimitarea f (n) = O(nlogb a ) implic existena unei constante c > 0 astfel nct pentru nj
suficient de mare,
logb a log a j logb a
n b n b b b
f (nj ) c j + =c 1+
b b1 aj n b1
log a logb a log a
n b b n b
= c j
1 + O ,
a b1 aj

deoarece c(1 + b/(b 1))logb a este o constant. Astfel, cazul 2 este demonstrat. Demonstraia
cazului 1 este aproape identic. Cheia este s demonstrm delimitarea f (nj ) = O(nlogb a ), care
este similar cu demonstraia corespunztoare din cazul 2, dei calculele sunt mai complicate.
Am demonstrat delimitrile superioare din teorema master pentru toi ntregii n. Demon-
straia delimitrilor inferioare este similar.

Exerciii
4.4-1 ? Dai o expresie simpl i exact pentru ni n ecuaia (4.12) pentru cazul n care b este
un ntreg pozitiv n loc de un numr real arbitrar.

4.4-2 ? Artai c dac f (n) = (nlogb a lgk n), unde k 0, atunci recurena master are soluia
T (n) = (nlogb a lgk+1 n). Pentru simplitate, limitai-v analiza la cazul puterilor exacte ale lui
b.

4.4-3 Artai c ipotezele cazului 3 din teorema master sunt abundente, n sensul c cerina de
regularitate af (n/b) cf (n) pentru o anumit constant c < 1 implic existena unei constante
> 0 astfel nct f (n) = (nlogb a+ ).

Probleme
4-1 Exemple de recurene
Dai margini asimptotice superioare i inferioare pentru fiecare dintre urmtoarele recurene.
Presupunei c T (n) este constant pentru n 2. Facei marginile ct de strnse se poate i
justificai a rspunsurile.

a. T (n) = 2T (n/2) + n3 .

b. T (n) = T (9n/10) + n.

c. T (n) = 16T (n/4) + n2 .

d. T (n) = 7T (n/3) + n2 .

e. T (n) = 7T (n/2) + n2 .

f. T (n) = 2T (n/4) + n.

g. T (n) = T (n 1) + n.
Probleme 63


h. T (n) = T ( n) + 1.

4-2 Gsirea ntregului lips


Un tablou A[1..n] conine toate valorile ntregi de la 0 la n, cu excepia unuia. Ar fi uor s
determinm ntregul lips n timp O(n) utiliznd un tablou auxiliar B[0..n] pentru a nregistra
numerele care apar n A. n aceast problem, totui, accesul complet la un element din A nu se
poate realiza printr-o singur operaie. Elementele lui A sunt reprezentate n binar, iar singura
operaie pe care o putem utiliza pentru a le accesa este extrage al j-lea bit al lui A[i], care cere
timp constant.
Artai c dac utilizm numai aceast operaie nc se mai poate determina ntregul lips
n timp O(n).

4-3 Costul transmiterii parametrilor


Pe parcursul acestei cri presupunem c transmiterea parametrilor n timpul apelrilor
procedurilor cere timp constant, chiar dac este transmis un tablou cu N elemente. Aceast
ipotez este valid n majoritatea sistemelor, deoarece nu este transmis tabloul nsui, ci un
pointer ctre tablou. Aceast problem examineaz implicaiile a trei strategii de transmitere a
parametrilor:
1. Un tablou este transmis prin pointer. Timpul este (1).
2. Un tablou este transmis prin copiere. Timpul este (N ), unde N este dimensiunea
tabloului.
3. Un tablou este transmis copiind numai subdomeniul care ar putea fi accesat de procedura
apelat. Timpul este (p q + 1) dac este transmis subtabloul A[p..q].
a. Considerai algoritmul recursiv de cutare binar pentru gsirea unui numr ntr-
un tablou sortat (vezi exerciiul 1.3-5). Dai recurene pentru timpul de execuie n
cazul cel mai defavorabil cnd tablourile sunt transmise utiliznd fiecare dintre cele
trei metode de mai sus i dai margini superioare bune pentru soluiile recurenelor.
Presupunem c dimensiunea problemei iniiale este N , iar dimensiunea subproblemei
este n.
b. Refacei partea (a) pentru algoritmul Sorteaz-Prin-Interclasare din seciunea
1.3.1.

4-4 Alte exemple de recurene


Dai margini asimptotice superioare i inferioare pentru T (n) pentru fiecare dintre urmtoarele
recurene. Presupunei c T (n) este constant pentru n 8. Facei marginile ct de strnse se
poate i justificai rspunsurile.
a. T (n) = 3T (n/2) + n lg n.
b. T (n) = 3T (n/3 + 5) + n/2.
c. T (n) = 2T (n/2) + n/ lg n.
d. T (n) = T (n 1) + 1/n.
e. T (n) = T (n 1) + lg n.
64 Capitolul 4 Recurene


f. T (n) = nT ( n) + n.

4-5 Condiii de pant


Adesea suntem n stare s delimitm o recuren T (n) pentru puterile exacte ale unei constante
ntregi b. Aceast problem ne d condiii suficiente pentru a extinde delimitarea la toate valorile
n > 0 reale.
a. Fie T (n) i h(n) funcii monoton cresctoare i s presupunem c T (n) h(n) cnd n
este o putere exact a unei constante b > 1. Mai mult, s presupunem c h(n) este lent
cresctoare, n sensul c h(n) = O(h(n/b)). Demonstrai c T (n) = O(h(n)).
b. S presupunem c avem recurena T (n) = aT (n/b) + f (n), unde a 1, b > 1, iar f (n) este
monoton cresctoare. Totodat condiiile iniiale pentru recuren sunt date de T (n) =
g(n) pentru n n0 , unde g(n) este monoton cresctoare, iar g(n0 ) aT (n0 /b) + f (n0 ).
Demonstrai c T (n) este monoton cresctoare.
c. Simplificai demonstraia teoremei master pentru cazul n care f (n) este monoton
cresctoare i lent cresctoare. Utilizai lema 4.4.

4-6 Numere Fibonacci


Aceast problem dezvolt proprieti ale numerolor lui Fibonacci, care sunt definite prin recu-
rena (2.13). Vom utiliza tehnica funciilor generatoare pentru a rezolva recurena lui Fibonacci.
S definim funcia generatoare (sau seria formal de puteri ) F ca

X
F(z) = Fi z i = 0 + z + z 2 + 2z 3 + 3z 4 + 5z 5 + 8z 6 + 13z 7 + 21z 8 + .
i=0

a. Artai c F(z) = z + F(z) + z 2 F(z).


b. Artai c

z z 1 1 1
F(z) = = = ,
1 z z2 b
(1 z)(1 z) 5 1 z b
1 z

unde

1+ 5 1 5
= = 1.61803 . . . i b = = 0.61803 . . . .
2 2

c. Artai c

X
1
F(z) = (i bi )z i .
i=0
5

d. Demonstrai c Fi = i / 5 pentru i > 0, rotunjit la cel mai apropiat ntreg. (Indicaie:
b < 1.)
||
e. Demonstrai c Fi+2 i pentru i 0.
Note bibliografice 65

4-7 Testarea chip-urilor VLSI


Profesorul Diogenes are n chip-uri VLSI1 presupuse a fi identice, care sunt capabile n principiu
s se testeze unele pe altele. Matria de testare a profesorului utilizeaz dou chip-uri deodat.
Cnd matria este ncrcat, fiecare chip l testeaz pe cellalt i raporteaz dac este bun sau
defect. Un chip bun raporteaz ntotdeauna corect dac cellalt cip este bun sau defect, dar
rspunsul unui chip defect nu este demn de ncredere. Astfel, cele patru rezultate posibile ale
testului sunt dup cum urmeaz:

Chip-ul A spune Chip-ul B spune Concluzie


B este bun A este bun ambele sunt bune sau ambele sunt defecte
B este bun A este defect cel puin unul este defect
B este defect A este bun cel puin unul este defect
B este defect A este defect cel puin unul este defect

a. Demonstrai c dac mai mult de de n/2 cip-uri sunt defecte, profesorul nu poate neaprat
s determine care cip-uri sunt bune, utiliznd orice strategie bazat pe acest tip de testare
pe perechi. Presupunei c cip-urile defecte pot conspira pentru a-l pcli pe profesor.
b. S considerm problema gsirii unui singur cip bun dintre n cip-uri, presupunnd c mai
mult de n/2 cip-uri sunt bune. Artai c bn/2c teste pe perechi sunt suficiente pentru a
reduce dimensiunea problemei la jumtate.
c. Artai c cip-urile bune pot fi identificate cu (n) teste pe perechi, presupunnd c mai
mult de n/2 cip-uri sunt bune. Dai i rezolvai recurena care descrie numrul de teste.

Note bibliografice
Recurenele au fost studiate nc din 1202 de ctre L. Fibonacci, dup care sunt denumite
numerele lui Fibonacci. A. De Moivre a introdus metoda funciilor generatoare (vezi problema
4-6) pentru rezolvarea recurenelor. Metoda master este adaptat din Bentley, Haken i Saxe
[26], care prezint metoda extins justificat prin exerciiul 4.4-2. Knuth [121] i Liu [140] arat
cum se rezolv recurenele liniare utiliznd metoda funciilor generatoare. Purdom i Brown [164]
conine o discuie extins asupra rezolvrii recurenelor.

1 VLSI nseamn very-large-scale-integration (integrare la scar foarte mare), care este tehnologia chip-urilor

de circuite integrate utilizat astzi pentru fabricarea majoritii microprocesoarelor.


5 Mulimi etc.

n capitolele anterioare am studiat unele noiuni matematice. n acest capitol vom recapitula
i vom completa notaiile, definiiile i proprietile elementare ale mulimilor, relaiilor, func-
iilor, grafurilor i arborilor. Cititorii familiarizai cu aceste noiuni trebuie, doar, s rsfoiasc
paginile acestui capitol.

5.1. Mulimi
O mulime este o colecie de obiecte distincte numite membri sau elemente. Dac un
obiect x este element al mulimii S, scriem x S i citim x este un element al lui S sau, mai
scurt, x aparine lui S. Dac x nu este un element al lui S, scriem x / S. Putem descrie o
mulime enumerndu-i elementele n mod explicit ca o list ntre acolade. De exemplu, putem
defini o mulime S care conine numerele 1, 2 i 3 scriind S = {1, 2, 3}. Deoarece 2 este un element
al mulimii S, vom scrie 2 S, dar vom scrie 4 / S deoarece 4 nu este un element al lui S. O
mulime nu poate conine acelai obiect de mai multe ori i elementele sale nu sunt ordonate.
Dou mulimi A i B sunt egale dac ele conin aceleai elemente. Notaia folosit pentru a arta
c dou mulimi sunt egale este A = B. De exemplu, avem {1, 2, 3, 1} = {1, 2, 3} = {3, 2, 1}.
Folosim notaii speciale pentru cteva mulimi mai des ntlnite.
Notm cu mulimea vid, adic mulimea care nu conine nici un element.
Notm cu Z mulimea numerelor ntregi, adic mulimea {. . . , 2, 1, 0, 1, 2, . . .}.
Notm cu R mulimea numerelor reale.
Notm cu N mulimea numerelor naturale, adic mulimea {0, 1, 2, . . .}.1
Dac toate elementele unei mulimi A sunt coninute ntr-o mulime B, adic dac x A
implic x B, atunci scriem A B i spunem c A este o submulime a lui B. O mulime A
este o submulime strict a lui B, notat A B, dac A B dar A 6= B. (Unii autori folosesc
simbolul pentru a nota relaia obinuit de incluziune i nu relaia de incluziune strict.)
Pentru orice mulime A, avem A A. Pentru dou mulimi A i B, avem A = B dac, i numai
dac, A B i B A. Pentru oricare trei mulimi A, B i C, dac A B i B C, atunci
A C. Pentru orice mulime A avem A.
Uneori definim mulimi pornind de la alte mulimi deja definite. Dndu-se o mulime A,
putem defini o mulime B A impunnd o restricie care s disting elementele din B de
celelalte elemente din A. De exemplu putem defini mulimea numerelor ntregi pare prin
x:xZ
i x/2 este un numr ntreg}. Cele dou puncte din notaia anterioar nseamn astfel nct.
(Unii autori folosesc o bar vertical n locul acestor dou puncte.)
1 Unii autori susin c 0 nu face parte din mulimea numerelor naturale. Totui tendina modern este de a

include i numrul 0 n aceast mulime.


5.1. Mulimi 67

Dndu-se dou mulimi A i B putem defini noi mulimi aplicnd unii operatori cu mul-
imi:
Intersecia mulimilor A i B este mulimea

A B = {x : x A i x B}.

Reuniunea mulimilor A i B este mulimea

A B = {x : x A sau x B}.

Diferena dintre dou mulimi A i B este mulimea

A B = {x : x A i x
/ B}.

Operaiile cu mulimi respect urmtoarele reguli:

Reguli ale mulimii vide:


A = ,
A = A.
Reguli de idempoten:
A A = A,
A A = A.
Reguli de comutativitate:
A B = B A,
A B = B A.
Reguli de asociativitate:
A (B C) = (A B) C,
A (B C) = (A B) C.
Reguli de distributivitate:
A (B C) = (A B) (A C),
(5.1)
A (B C) = (A B) (A C).
Reguli de absorbie:
A (A B) = A,
A (A B) = A.
Legile lui DeMorgan:
A (B C) = (A B) (A C),
(5.2)
A (B C) = (A B) (A C).
68 Capitolul 5 Mulimi etc.

Figura 5.1 O diagram Venn ilustrnd prima regul a lui DeMorgan (5.2). Fiecare dintre mulimile
A, B i C este reprezentat ca un cerc n plan.

Prima dintre regulile lui DeMorgan este ilustrat n figura 5.1, folosind o diagram Venn,
o imagine grafic n care mulimile sunt reprezentate ca regiuni n plan.
Deseori toate mulimile considerate sunt submulimi ale unei mulimi mai mari U numit
univers. De exemplu, dac lum n considerare diferite mulimi formate numai din ntregi, mul-
imea Z este un univers potrivit. Dndu-se un univers U , definim complementul unei mulimi
A ca fiind A = U A. Pentru orice mulime A U , urmtoarele propoziii sunt adevrate:

A = A,
AA = ,
AA = U.

Dndu-se dou mulimi A, B U , regulile lui DeMorgan pot fi rescrise cu ajutorul complemen-
telor mulimilor A i B fa de U astfel:

A B = A B,
A B = A B.

Dou mulimi A i B sunt disjuncte dac nu au nici un element comun, adic A B = .


O colecie S = {Si } de mulimi nevide formeaz o partiie a unei mulimi S dac:

mulimile sunt distincte dou cte dou, adic Si , Sj S i i 6= j implic Si Sj = i

reuniunea lor este S, adic


[
S= Si
Si S.

Cu alte cuvinte, S formeaz o partiie a lui S dac fiecare element al mulimii S apare n exact
o mulime Si S.
Numrul de elemente ale unei mulimi poart denumirea de cardinal (sau dimensiune)
al mulimii i este notat cu |S|. Dou mulimi au acelai cardinal dac poate fi stabilit o
coresponden biunivoc ntre cele dou mulimi. Cardinalul mulimii vide este || = 0. n
cazul n care cardinalul unei mulimi este un numr natural, spunem c mulimea este finit;
altfel, ea este infinit. O mulime infinit care poate fi pus n coresponden biunivoc cu
mulimea numerelor naturale N este numit mulime numrabil infinit; n caz contrar
5.1. Mulimi 69

ea este nenumrabil. Mulimea Z a numerelor ntregi este numrabil dar mulimea R a


numerelor reale este nenumrabil.
Pentru oricare dou mulimi finite A i B, avem identitatea:

|A B| = |A| + |B| |A B|, (5.3)

de unde putem deduce c

|A B| |A| + |B|.

Dac A i B sunt disjuncte, atunci |A B| = 0, deci |A B| = |A| + |B|. Dac A B, atunci


|A| |B|.
O mulime finit cu n elemente este uneori denumit n-mulime. O 1-mulime este denumit
mulime cu un singur element. O submulime cu k elemente a unei mulimi este denumit
uneori k-submulime.
Mulimea tuturor submulimilor unei mulimi S, incluznd mulimea vid i mulimea
S, este notat prin 2S i este denumit mulimea prilor lui S. De exemplu, 2{a,b} =
{, {a}, {b}, {a, b}}. Mulimea prilor unei mulimi finite S are cardinalul 2|S| .
Uneori ne intereseaz structuri asemntoare mulimilor n cadrul crora elementele sunt
ordonate. O pereche ordonat format din dou elemente a i b este notat cu (a, b) i poate
fi definit ca fiind mulimea (a, b) = {a, {a, b}}. Deci perechea ordonat (a, b) nu este identic
cu perechea ordonat (b, a).
Produsul cartezian a dou mulimi A i B, notat prin A B, este mulimea tuturor pere-
chilor ordonate astfel nct primul element al perechii face parte din mulimea A, iar al doilea
este un element al mulimii B. Mai exact:

A B = {(a, b) : a A i b B}.

De exemplu {a, b} {a, b, c} = {(a, a), (a, b), (a, c), (b, a), (b, b), (b, c)}. Cnd A i B sunt mulimi
finite, cardinalul produsului lor cartezian este:

|A B| = |A| |B|. (5.4)

Produsul cartezian a n mulimi A1 , A2 , . . . , An este o mulime de n-tuple

A1 A2 An = {(a1 , a2 , . . . , an ) : ai Ai , i = 1, 2, . . . , n},

al crei cardinal este:

|A1 A2 An | = |A1 | |A2 | |An |,

dac toate mulimile sunt finite. Notm produsul cartezian dintre o mulime A i ea nsi prin

A2 = A A.

Similar, avem:

An = A A A.

Cardinalul acestei ultime mulimi este |An | = |A|n dac A este finit. Un n-tuplu poate fi privit
ca un ir finit de lungime n (vezi seciunea 5.3).
70 Capitolul 5 Mulimi etc.

Exerciii
5.1-1 Desenai diagramele Venn care ilustreaz prima regul de distributivitate (5.1).

5.1-2 Demonstrai regulile generalizate ale lui DeMorgan pentru orice colecie finit de mulimi:

A1 A2 An = A1 A2 An ,
A1 A2 An = A1 A2 An .

5.1-3 ? Demonstrai generalizarea ecuaiei (5.3), care este denumit principiul includerii i
al excluderii:
|A1 A2 An | =
|A1 | + |A2 | + + |An |
|A1 A2 | |A1 A3 | (toate perechile)
+|A1 A2 A3 | + (toate tripletele)
..
.
+(1)n1 |A1 A2 An |.

5.1-4 Artai c mulimea numerelor naturale impare este numrabil.

5.1-5 Artai c, pentru orice mulime finit S, mulimea prilor sale 2S are 2|S| elemente
(adic exist 2|S| submulimi distincte ale lui S).

5.1-6 Dai o definiie inductiv pentru un n-tuplu extinznd definiia perechii ordonate din
teoria mulimilor.

5.2. Relaii
O relaie binar R ntre dou mulimi A i B este o submulime a produsului cartezian
AB. Dac (a, b) R, folosim uneori notaia a R b. Cnd spunem c R este o relaie binar peste
o mulime A, nelegem c R este o submulime a produsului cartezian AA. De exemplu, relaia
mai mic dect peste mulimea numerelor naturale este mulimea {(a, b) : a, b N i a < b}. O
relaie n-ar ntre mulimile A1 , A2 , . . . , An este o submulime a lui A1 A2 An .
O relaie binar R A A este reflexiv dac

aRa

pentru orice a A. De exemplu, = i sunt relaii reflexive peste N n timp ce relaia <
nu este. Relaia R este simetric dac

a R b implic b R a

pentru orice a, b A. De exemplu, = este simetric, dar < i nu sunt. Relaia R este
tranzitiv dac

a R b i b R c implic a R c
5.2. Relaii 71

pentru orice a, b, c A. De exemplu, relaiile <, i = sunt tranzitive, dar relaia R =


{(a, b) : a, b N i a = b 1} nu este deoarece 3 R 4 i 4 R 5 nu implic 3 R 5.
O relaie care este reflexiv, simetric i tranzitiv poart denumirea de relaie de
echivalen. De exemplu = este o relaie de echivalen peste mulimea numerelor naturale
n timp ce < nu este. Dac R este o relaie de echivalen peste o mulime A, atunci pentru
oricare a A, clasa de echivalen a lui a este mulimea [a] = {b A : a R b}, adic
mulimea tuturor elementelor echivalente cu a. De exemplu, dac definim R = {(a, b) : a, b
N i a + b este un numr par}, atunci R este o relaie de echivalen deoarece a + a este par
(reflexivitate), dac a + b este par atunci i b + a este par (simetrie) i, dac a + b este par
i b + c este par, atunci i a + c este par (tranzitivitate). Clasa de echivalen a lui 4 este
[4] = {0, 2, 4, 6, . . .}, iar clasa de echivalen a lui 3 este [3] = {1, 3, 5, 7, . . .}. O teorem de baz
n studiul claselor de echivalen este urmtoarea.

Teorema 5.1 (O relaie de echivalen este identic cu o partiie) Clasele de echiva-


len ale oricrei relaii de echivalen R peste o mulime A formeaz o partiie a lui A i
oricare partiie a lui A determin a relaie de echivalen peste A pentru care mulimile din
partiie sunt clase de echivalen.

Demonstraie. Pentru prima parte a demonstraiei, trebuie s artm c clasele de echivalen


ale lui R sunt nevide, disjuncte dou cte dou i reuniunea lor este A. Deoarece R este reflexiv,
a [a], clasele de echivalen sunt nevide; mai mult, deoarece fiecare element a A aparine
clasei de echivalen [a], reuniunea claselor de echivalen este A. Rmne de artat c clasele
de echivalen sunt distincte dou cte dou, adic dac dou clase de echivalen [a] i [b] au
un element c comun, ele sunt, de fapt, identice. Avem a R c i b R c de unde deducem (datorit
proprietilor de simetrie i tranzitivitate ale lui R) c a R b. Deci, pentru oricare element x [a]
avem x R a implic x R b, deci [a] [b]. Similar, putem demonstra c [b] [a], deci [a] = [b].
Pentru a doua parte a demonstraiei, fie A = {Ai } o partiie a mulimii A. Definim relaia
R = {(a, b) : exist i astfel nct a Ai i b Ai }. Susinem c R este o relaie de echivalen
peste A. Proprietatea de reflexivitate este respectat deoarece a Ai implic a R a. Proprietatea
de simetrie este i ea respectat deoarece dac a R b atunci a i b fac parte din aceeai mulime
Ai , deci b R a. Dac a R b i b R c atunci toate cele trei elemente se afl n aceeai mulime, deci
b R a i proprietatea de tranzitivitate este respectat. Pentru a vedea c mulimile partiiei sunt
clase de echivalen ale lui R, observai c, dac a Ai , atunci x [a] implic x Ai i x Ai
implic x [a].
O relaie binar R peste o mulime A este antisimetric dac
a R b i b R a implic a = b.
De exemplu, relaia peste mulimea numerelor naturale este antisimetric deoarece a b
i b a implic a = b. O relaie care este reflexiv, antisimetric i tranzitiv este o relaie
de ordine parial. O mulime peste care este definit o relaie de ordine parial poart
denumirea de mulime parial ordonat. De exemplu, relaia este descendent al lui este
o relaie de ordine parial a mulimii tuturor fiinelor umane (dac privim indivizii ca fiind
propriii lor descendeni).
ntr-o mulime parial ordonat A, poate s nu existe un singur element maxim x, astfel
nct y R x pentru orice y A. Pot exista mai multe elemente maximale x, astfel nct pentru
nici un y A nu exist relaia x R y. De exemplu, ntr-o colecie de cutii avnd diferite dimensiuni
72 Capitolul 5 Mulimi etc.

pot exista mai multe cutii maximale care nu pot fi introduse n interiorul nici unei alte cutii,
neexistnd totui nici o cutie maxim n interiorul creia s poat fi introduse toate celelalte
cutii.
O relaie parial de ordine R peste o mulime A este o relaie de ordine total sau re-
laie de ordine liniar dac pentru orice a, b A avem a R b sau b R a, adic orice pereche
de elemente din A poate fi pus n relaie de ctre R. De exemplu, relaia este o relaie de
ordine total peste mulimea numerelor naturale, dar relaia este descendent al lui nu este o
relaie de ordine total peste mulimea tuturor fiinelor umane deoarece exist perechi de indivizi
pentru care nici unul nu este descendentul celuilalt.

Exerciii
5.2-1 Demonstrai c relaia de incluziune peste toate submulimile lui Z este o relaie de
ordine parial, dar nu este o relaie de ordine total.

5.2-2 Artai c, pentru orice ntreg pozitiv n, relaia de echivalen modulo n este o relaie
de echivalen peste mulimea numerelor ntregi. (Spunem c a b (mod n) dac exist un
numr ntreg q astfel nct a b = qn.) n ce clase de echivalen partiioneaz aceast relaie
mulimea numerelor ntregi?

5.2-3 Dai exemple de relaii care sunt:

a. reflexive i simetrice, dar netranzitive,

b. reflexive i tranzitive, dar nesimetrice,

c. simetrice i tranzitive, dar nereflexive.

5.2-4 Fie S o mulime finit i R o relaie de echivalen peste S S. Artai c, dac R este
i antisimetric, atunci clasele de echivalen ale lui S fa de R sunt mulimi unitate.

5.2-5 Profesorul Narcissus susine c, dac o relaie este simetric i tranzitiv, ea este i re-
flexiv. El ofer urmtoarea demonstraie: prin simetrie a R b implic b R a, deci tranzitivitatea
implic a R a. Are profesorul dreptate?

5.3. Funcii
Dndu-se dou mulimi A i B, o funcie este o relaie binar peste A B astfel nct,
pentru orice a A, exist exact un b B, i (a, b) f . Mulimea A este numit domeniul lui
f , iar mulimea B este numit codomeniul lui f . Uneori, scriem f : A B i, dac (a, b) f ,
scriem b = f (a), deoarece b este unic determinat prin alegerea lui a.
Intuitiv, funcia f atribuie fiecrui element din A un element din B. Nici unui element din
A nu i se atribuie dou elemente diferite din B, dar acelai element din B poate fi atribuit mai
multor elemente diferite din A. De exemplu, relaia binar

f = {(a, b) : a N i b = a mod 2}
5.3. Funcii 73

este o funcie f : N {0, 1}, deoarece pentru fiecare numr natural a exist exact o valoare b
n {0, 1} astfel nct b = a mod 2. Pentru acest exemplu avem 0 = f (0), 1 = f (1), 0 = f (2) etc.
n schimb, relaia binar
g = {(a, b) : a N i a + b este par}
nu este o funcie deoarece att (1, 3) ct i (1, 5) se afl n g, deci dac alegem a = 1 nu putem
determina un singur b pentru care (a, b) g.
Dndu-se o funcie f : A B dac b = f (a), spunem c a este argumentul lui f , iar b
este valoarea lui f n punctul a. Putem defini o funcie enumernd valorile sale pentru fiecare
element din domeniu. De exemplu, putem defini f (n) = 2n pentru n N, ceea ce nseamn
f = {(n, 2n) : n N}. Dou funcii f i g sunt egale dac au acelai domeniu, acelai codomeniu
i, pentru orice a din domeniu, avem f (a) = g(a).
Un ir finit de lungime n este o funcie f al crei domeniu este mulimea {0, 1, . . . , n 1}.
Deseori, definim un ir finit prin enumerarea valorilor sale: hf (0), f (1), . . . , f (n 1)i. Un ir
infinit este o funcie al crei domeniu este mulimea numerelor naturale N. De exemplu, irul
lui Fibonacci, definit prin (2.13), este irul infinit h0, 1, 1, 2, 3, 5, 8, 13, 21, . . .i.
Cnd domeniul unei funcii f este un produs cartezian, omitem adesea perechea suplimentar
de paranteze n care este cuprins argumentul lui f . De exemplu, dac f : A1 A2 An B,
vom scrie b = f (a1 , a2 , . . . , an ) n loc de a scrie b = f ((a1 , a2 , . . . , an )). De asemenea, vom numi
fiecare ai un argument al lui f , cu toate c singurul argument veritabil al lui f este n-tuplul
(a1 , a2 , . . . , an ).
Dac f : A B este o funcie i b = f (a), uneori, spunem c b este imaginea lui a prin f .
Imaginea unei mulimi A0 A prin f este definit prin:
f (A0 ) = {b B : b = f (a) pentru a A0 }.
Domeniul de valori al unei funcii este imaginea domeniului su, adic f (A). De exemplu
imaginea funciei f : N N definit prin f (n) = 2n este f (N) = {m : m = 2n pentru n N}.
O funcie este o surjecie dac imaginea sa este egal cu codomeniul su. De exemplu, funcia
f (n) = bn/2c este o funcie surjectiv de la N la N deoarece fiecare element din N este valoare a
lui f pentru un anumit argument. n schimb, funcia f (n) = 2n nu este o funcie surjectiv de
la N la N deoarece pentru nici un argument funcia nu ia valoarea 3. Funcia f (n) = 2n este,
totui, o funcie surjectiv de la mulimea numerelor naturale la mulimea numerelor pare.
O funcie f : A B este o injecie dac, pentru argumente distincte, avem valori distincte
ale funciei, adic a 6= a0 implic f (a) 6= f (a0 ). De exemplu funcia f (n) = 2n este o funcie
injectiv de la N la N deoarece fiecare numr par b este imaginea prin f a cel mult un element
din domeniu, mai precis a lui b/2. Funcia f (n) = bn/2c nu este injectiv deoarece ia valoarea 1
pentru mai multe argumente: 2 i 3. O injecie se numete uneori funcie unu-la-unu.
O funcie f : A B este o bijecie dac este injectiv i surjectiv. De exemplu, funcia
f (n) = (1)n dn/2e este o bijecie de la N la Z:
0 0,
1 1,
2 1,
3 2,
4 2,
..
.
74 Capitolul 5 Mulimi etc.

Funcia este injectiv, deoarece nici un element din Z nu este imagine a mai multor elemente din
N, i surjectiv, deoarece fiecare element din Z este imagine a unui element din N. n concluzie,
funcia este bijectiv. O bijecie este uneori numit i coresponden unu-la-unu deoarece
mperecheaz elemente din domeniu i codomeniu. O bijecie de la o mulime A la ea nsi
este uneori numit o permutare.
Cnd o funcie f este bijectiv inversa ei f 1 este definit prin:
f 1 (b) = a dac i numai dac f (a) = b.
De exemplu, inversa funciei f (n) = (1)n dn/2e este

2m dac m 0,
f 1 (m) =
2m 1 dac m < 0.

Exerciii
5.3-1 Fie A i B dou mulimi finite i o funcie f : A B. Artai c:
a. dac f este injectiv atunci |A| |B|;
b. dac f este surjectiv atunci |A| |B|.

5.3-2 Verificai dac funcia f (x) = x + 1 este bijectiv n cazul n care domeniul i codomeniul
sunt N. Dar dac domeniul i codomeniul sunt Z?

5.3-3 Dai o definiie natural pentru inversa unei relaii binare, astfel nct dac o relaie
binar este, de fapt, o funcie bijectiv, atunci inversa relaiei este inversa funciei.

5.3-4 ? Dai o bijecie ntre Z i Z Z.

5.4. Grafuri
Aceast seciune prezint dou tipuri de grafuri: orientate i neorientate. Cititorul trebuie
avizat c anumite definiii din literatura de specialitate difer de cele prezentate aici, dar n cele
mai multe cazuri diferenele sunt minore. Seciunea 23.1 arat cum pot fi reprezentate grafurile
n memoria calculatorului.
Un graf orientat (sau digraf) G este o pereche (V, E), unde V este o mulime finit, iar E
este o relaie binar pe V . Mulimea V se numete mulimea vrfurilor lui G, iar elementele
ei se numesc vrfuri. Mulimea E se numete mulimea arcelor lui G, i elementele ei se nu-
mesc arce. Figura 5.2(a) este o reprezentare grafic a unui graf orientat cu mulimea de vrfuri
{1, 2, 3, 4, 5, 6}. n figur, vrfurile sunt reprezentate prin cercuri, iar arcele prin sgei. Observai
c sunt posibile autobuclele arce de la un vrf la el nsui.
ntr-un graf neorientat G = (V, E), mulimea muchiilor E este constituit din perechi
de vrfuri neordonate, i nu din perechi ordonate. Cu alte cuvinte, o muchie este o mulime
{u, v}, unde u, v V i u 6= v. Prin convenie, pentru o muchie vom folosi notaia (u, v) n locul
notaiei pentru mulimi {u, v}, iar (u, v) i (v, u) sunt considerate a fi aceeai muchie. ntr-un
graf neorientat, autobuclele sunt interzise i astfel fiecare muchie este format din exact dou
5.4. Grafuri 75

Figura 5.2 Grafuri orientate i neorientate. (a) Un graf orientat G = (V, E), unde V = {1, 2, 3, 4, 5, 6}
i E = {(1, 2), (2, 2), (2, 4), (2, 5), (4, 1), (4, 5), (5, 4), (6, 3)}. Arcul (2, 2) este o autobucl. (b) Un graf
neorientat G = (V, E), unde V = {1, 2, 3, 4, 5, 6} i E = {(1, 2), (1, 5), (2, 5), (3, 6)}. Vrful 4 este izolat.
(c) Subgraful grafului de la (a) indus de mulimea de vrfuri {1, 2, 3, 6}.

vrfuri distincte. Figura 5.2(b) este o reprezentare grafic a unui graf neorientat avnd mulimea
de vrfuri {1, 2, 3, 4, 5, 6}.
Multe definiii pentru grafuri orientate i neorientate sunt aceleai, dei anumii termeni pot
avea semnificaii diferite n cele dou contexte. Dac (u, v) este un arc ntr-un graf orientat
G = (V, E), spunem c (u, v) este incident din sau pleac din vrful u i este incident n
sau intr n vrful v. De exemplu, arcele care pleac din vrful 2, n figura 5.2(a), sunt (2, 2),
(2, 4) i (2, 5). Arcele care intr n vrful 2 sunt (1, 2) i (2, 2). Dac (u, v) este o muchie ntr-un
graf neorientat G = (V, E), spunem c (u, v) este incident vrfurilor u i v. n figura 5.2(b),
muchiile incidente vrfului 2 sunt (1, 2) i (2, 5).
Dac (u, v) este o muchie (arc) ntr-un graf G = (V, E), spunem c vrful v este adiacent
vrfului u. Atunci cnd graful este neorientat, relaia de adiacen este simetric. Cnd graful
este orientat, relaia de adiacen nu este neaprat simetric. Dac v este adiacent vrfului u
ntr-un graf orientat, uneori scriem u v. n prile (a) i (b) ale figurii 5.2, vrful 2 este
adiacent vrfului 1, deoarece muchia (arcul) (1, 2) aparine ambelor grafuri. Vrful 1 nu este
adiacent vrfului 2 n figura 5.2(a), deoarece muchia (2, 1) nu aparine grafului.
Gradul unui vrf al unui graf neorientat este numrul muchiilor incidente acestuia. De exem-
plu, vrful 2, din figura 5.2(b), are gradul 2. Un vrf al crui grad este 0, cum este, de exemplu,
vrful 4, din figura 5.2(b), se numete vrf izolat. ntr-un graf orientat, gradul exterior al
unui vrf este numrul arcelor ce pleac din el, iar gradul interior al unui vrf este numrul
arcelor ce intr n el. Gradul unui vrf al unui graf orientat este gradul su interior, plus gradul
su exterior. Vrful 2 din figura 5.2(a) are gradul interior 2, gradul exterior 3 i gradul 5.
Un drum de lungime k de la un vrf u la un vrf u0 ntr-un graf G = (V, E) este un ir
de vrfuri hv0 , v1 , v2 , ..., vk i astfel nct u = v0 , u0 = vk , i (vi1 , vi ) E pentru i = 1, 2, ..., k.
Lungimea unui drum este numrul de muchii (arce) din acel drum. Drumul conine vrfurile
v0 , v1 , v2 , ..., vk i muchiile (v0 , v1 ), (v1 , v2 ), ..., (vk1 , vk ). Dac exist un drum p de la u la u0 ,
p
spunem c u0 este accesibil din u prin p, relaie reprezentat uneori prin u ; u0 dac G este
orientat. Un drum este elementar dac toate vrfurile din el sunt distincte. n figura 5.2(a),
drumul h1, 2, 5, 4i este un drum elementar de lungime 3. Drumul h2, 5, 4, 5i nu este elementar.
Un subdrum al unui drum p = hv0 , v1 , ..., vk i este un subir continuu al vrfurilor sale. Cu
76 Capitolul 5 Mulimi etc.

alte cuvinte, pentru orice 0 i j k, subirul de vrfuri hvi , vi+1 , ..., vj i este un subdrum al
lui p.
ntr-un graf orientat, un drum hv0 , v1 , ..., vk i formeaz un ciclu dac v0 = vk i drumul
conine cel puin o muchie. Ciclul este elementar dac, pe lng cele de mai sus, v1 , v2 , ..., vk
sunt distincte. O autobucl este un ciclu de lungime 1. Dou drumuri hv0 , v1 , v2 , ..., vk1 , v0 i
i hv00 , v10 , v20 , ..., vk1
0
, v00 i formeaz acelai ciclu dac exist un numr ntreg j astfel nct vi0 =
v(i+j) mod k pentru i = 0, 1, ..., k 1. n figura 5.2(a), drumul h1, 2, 4, 1i formeaz acelai ciclu
ca drumurile h2, 4, 1, 2i i h4, 1, 2, 4i. Acest ciclu este elementar, dar ciclul h1, 2, 4, 5, 4, 1i nu este
elementar. Ciclul h2, 2i format de muchia (2, 2) este o autobucl. Un graf orientat fr autobucle
este elementar. ntr-un graf neorientat, un drum hv0 , v1 , ..., vk i formeaz un ciclu elementar
dac k > 3, v0 = vk i vrfurile v1 , v2 , ..., vk sunt distincte. De exemplu, n figura 5.2(b), drumul
h1, 2, 5, 1i este un ciclu. Un graf fr cicluri este aciclic.
Un graf neorientat este conex dac fiecare pereche de vrfuri este conectat printr-un drum.
Componentele conexe ale unui graf sunt clasele de echivalen ale vrfurilor sub relaia este
accesibil din. Graful din figura 5.2(b) are trei componente conexe: {1, 2, 5}, {3, 6}, i {4}. Fiecare
vrf din {1, 2, 5} este accesibil din fiecare vrf din {1, 2, 5}. Un graf neorientat este conex dac
are exact o component conex, sau, altfel spus, dac fiecare vrf este accesibil din fiecare vrf
diferit de el.
Un graf orientat este tare conex dac fiecare dou vrfuri sunt accesibile din cellalt. Com-
ponentele tare conexe ale unui graf sunt clasele de echivalen ale vrfurilor sub relaia
sunt reciproc accesibile. Un graf orientat este tare conex dac are doar o singur component
tare conex. Graful din figura 5.2(a) are trei componente tare conexe: {1, 2, 4, 5}, {3}, i {6}.
Toate perechile de vrfuri din {1, 2, 4, 5} sunt reciproc accesibile. Vrfurile {3, 6} nu formeaz o
component tare conex, deoarece vrful 6 nu este accesibil din vrful 3.
Dou grafuri G = (V, E) i G0 = (V 0 , E 0 ) sunt izomorfe dac exist o bijecie f : V V 0
astfel nct (u, v) E dac, i numai dac, (f (u), f (v)) E 0 . Cu alte cuvinte, putem reeticheta
vrfurile lui G pentru ca acestea s fie vrfuri din G0 , pstrnd muchiile corespunztoare din
G i G0 . Figura 5.3(a) prezint o pereche de grafuri izomorfe G i G0 cu mulimile de vrfuri
V = {1, 2, 3, 4, 5, 6} i V 0 = {u, v, w, x, y, z}. Funcia din V n V 0 , dat de f (1) = u, f (2) = v,
f (3) = w, f (4) = x, f (5) = y, f (6) = z, este funcia bijectiv cerut. Grafurile din figura 5.3(b)
nu sunt izomorfe. Dei ambele grafuri au 5 vrfuri i 7 muchii, graful din partea superioar are
un vrf cu gradul egal 4, n timp ce graful din partea inferioar a figurii nu posed un astfel de
vrf.
Spunem c un graf G0 = (V 0 , E 0 ) este un subgraf al grafului G = (V, E) dac V 0 V i
E E. Dat fiind o mulime V 0 V , subgraful lui G indus de V 0 este graful G0 = (V 0 , E 0 ),
0

unde
E 0 = {(u, v) E : u, v V 0 }.
Subgraful indus de mulimea de vrfuri {1, 2, 3, 6}, din figura 5.2(a), apare n figura 5.2(c) i are
mulimea de muchii {(1, 2), (2, 2), (6, 3)}.
Dat fiind un graf neorientat G = (V, E), versiunea orientat a lui G este graful orientat
G0 = (V, E 0 ), unde (u, v) E 0 dac, i numai dac, (u, v) E. Cu alte cuvinte, fiecare muchie
neorientat (u, v) din G este nlocuit n versiunea orientat prin dou arce orientate: (u, v)
i (v, u). Dat fiind un graf orientat G = (V, E), versiunea neorientat a lui G este graful
neorientat G0 = (V, E 0 ), unde (u, v) E 0 dac, i numai dac, u 6= v i (u, v) E. Deci versiunea
neorientat conine arcele lui G cu direciile eliminate i cu autobuclele eliminate. (Deoarece
5.4. Grafuri 77

Figura 5.3 (a) O pereche de grafuri izomorfe. Corespondena dintre vrfurile grafului de sus i cele
ale grafului de jos este realizat prin funcia dat de f (1) = u, f (2) = v, f (3) = w, f (4) = x, f (5) = y,
f (6) = z. (b) Dou grafuri care nu sunt izomorfe, deoarece graful de sus are un vrf de grad 4, iar graful
de jos nu.

(u, v) i (v, u) reprezint aceeai muchie ntr-un graf neorientat, versiunea neorientat a unui
graf orientat o conine o singur dat, chiar dac graful orientat conine att muchia (u, v) ct
i muchia (v, u).) ntr-un graf orientat G = (V, E), un vecin al unui vrf u este orice vrf care
este adiacent lui u n versiunea neorientat a lui G. Deci v este un vecin al lui u dac (u, v) E
sau (v, u) E. ntr-un graf neorientat, u i v sunt vecine dac sunt adiacente.
Mai multe tipuri de grafuri poart nume speciale. Un graf complet este un graf neorientat
n care oricare dou vrfuri sunt adiacente. Un graf bipartit este un graf neorientat G = (V, E)
n care mulimea V poate fi partiionat n dou mulimi V1 i V2 astfel nct (u, v) E implic
fie c u V1 i v V2 , fie c u V2 i v V1 . Cu alte cuvinte, toate muchiile merg de la
mulimea V1 la mulimea V2 sau invers. Un graf neorientat, aciclic este o pdure, iar un graf
neorientat, aciclic i conex este un arbore (liber) (vezi seciunea 5.5).
Exist dou variante de grafuri care pot fi ntlnite ocazional. Un multigraf seamn cu un
graf neorientat, ns poate avea att muchii multiple ntre vrfuri ct i autobucle. Un hipergraf
seamn, de asemenea, cu un graf neorientat, dar fiecare hipermuchie, n loc de a conecta
dou vrfuri, conecteaz o submulime arbitrar de vrfuri. Muli algoritmi scrii pentru grafuri
orientate i neorientate obinuite pot fi adaptai pentru a rula pe aceste structuri asemntoare
grafurilor.

Exerciii

5.4-1 Invitaii unei petreceri studeneti i strng minile cnd se salut unul pe cellalt, i
fiecare profesor i amintete de cte ori a salutat pe cineva. La sfritul petrecerii, decanul
facultii nsumeaz numrul strngerilor de mn fcute de fiecare profesor. Artai c rezultatul
este par demonstrnd lema strngerilor de mn: dac G = (V, E) este un graf neorientat,
78 Capitolul 5 Mulimi etc.

atunci
X
grad(v) = 2|E|.
vV

5.4-2 Artai c, dac un graf orientat sau neorientat conine un drum ntre dou vrfuri u i
v, atunci conine un drum elementar ntre u i v. Artai c dac un graf orientat conine un
ciclu, atunci conine i un ciclu elementar.

5.4-3 Artai c orice graf neorientat, conex G = (V, E) satisface relaia |E| |V | 1.

5.4-4 Verificai faptul c, ntr-un graf neorientat, relaia este accesibil din este o relaie de
echivalen pe vrfurile grafului. Care din cele trei proprieti ale unei relaii de echivalen sunt
n general adevrate pentru relaia este accesibil din pe vrfurile unui graf orientat?

5.4-5 Care este versiunea neorientat a grafului orientat din figura 5.2(a)? Care este versiunea
orientat a grafului neorientat din figura 5.2(b)?

5.4-6 ? Artai c un hipergraf poate fi reprezentat printr-un graf bipartit dac stabilim ca
incidena n hipergraf s corespund adiacenei n graful bipartit. (Indicaie: Presupunei c o
mulime de vrfuri din graful bipartit corespunde vrfurilor din hipergraf, iar cealalt mulime
de vrfuri a grafului bipartit corespunde hipermuchiilor.)

5.5. Arbori
La fel ca n cazul grafurilor, exist multe noiuni de arbori nrudite, dar uor diferite. Aceast
seciune prezint definiii i proprieti matematice pentru mai multe tipuri de arbori. Seciunile
11.4 i 23.1 descriu modurile de reprezentare a arborilor n memoria calculatorului.

5.5.1. Arbori liberi


Dup cum a fost definit n seciunea 5.4, un arbore liber este un graf neorientat, aciclic i
conex. Deseori omitem adjectivul liber atunci cnd spunem c un graf este un arbore. Dac un
graf neorientat este aciclic, dar s-ar putea s nu fie conex, el formeaz o pdure. Muli algoritmi
pentru arbori funcioneaz, de asemenea, i pe pduri. Figura 5.4(a) prezint un arbore liber, iar
figura 5.4(b) prezint o pdure. Pdurea din figura 5.4(b) nu este un arbore pentru c nu este
conex. Graful din figura 5.4(c) nu este nici arbore i nici pdure, deoarece conine un ciclu.
Urmtoarea teorem prezint ntr-o form concentrat multe proprietai importante ale
arborilor liberi.

Teorema 5.2 (Proprietile arborilor liberi) Fie G = (V, E) un graf neorientat. Urmtoa-
rele afirmaii sunt adevrate:

1. G este un arbore liber.

2. Oricare dou vrfuri din G sunt conectate printr-un drum elementar unic.
5.5. Arbori 79

Figura 5.4 (a) Un arbore liber. (b) O pdure. (c) Un graf ce conine un ciclu, motiv pentru care nu
este nici arbore, nici pdure.

Figura 5.5 Un pas n demonstraia teoremei 5.2. Dac (1) G este un arbore liber, atunci (2) oricare
dou vrfuri din G sunt conectate printr-un unic drum elementar. S presupunem, prin absurd, c vr-
furile u i v sunt conectate prin dou drumuri simple distincte p1 i p2 . Aceste drumuri se despart pentru
prima dat n vrful w, i se rentlnesc pentru prima oar n vrful z. Drumul p0 mpreun cu inversul
drumului p00 formeaz un ciclu, de unde rezult o contradicie.

3. G este conex, dar, dac eliminm o muchie oarecare din E, graful obinut nu mai este
conex.

4. G este conex, i |E| = |V | 1.

5. G este aciclic, i |E| = |V | 1.

6. G este aciclic, dar, dac adugm o muchie oarecare n E, graful obinut conine un ciclu.

Demonstraie. (1) (2): Deoarece un arbore este conex, oricare dou vrfuri din G sunt
conectate prin cel puin un drum elementar. Fie u i v dou vrfuri care sunt conectate prin
dou drumuri distincte p1 i p2 , dup cum este prezentat n figura 5.5. Fie w vrful unde drumurile
se despart pentru prima dat. Cu alte cuvinte, w este primul vrf, att din p1 ct i din p2 , al
crui succesor n p1 este x i al crui succesor din p2 este y, cu x 6= y. Fie z primul vrf unde
drumurile se rentlnesc, adic z este primul vrf de dup w din p1 care se afl de asemenea i
n p2 . Fie p0 subdrumul din p1 de la w la z i care trece prin x, i fie p00 drumul din p2 de la w
la z i care trece prin y. Drumurile p0 i p00 nu au nici un vrf comun cu excepia vrfurilor lor
terminale. Astfel, drumul obinut, alturnd lui p0 inversul lui p00 , este un ciclu. Aceasta este o
contradicie i deci, dac G este un arbore, nu poate exista dect cel mult un drum elementar
ntre dou vrfuri.
(2) (3): Dac oricare dou vrfuri din G sunt conectate printr-un drum elementar, atunci
G este conex. Fie (u, v) o muchie oarecare din E. Aceast muchie este un drum de la u la v, i,
deci, trebuie s fie drumul unic dintre u i v. Dac eliminm muchia (u, v) din G, nu mai exist
nici un drum ntre u i v i, astfel, eliminarea ei face ca G s nu mai fie conex.
80 Capitolul 5 Mulimi etc.

(3) (4): Din ipotez, graful G este conex, iar din exerciiul 5.4-3 avem |E| |V | 1. Vom
demonstra relaia |E| |V | 1 prin inducie. Un graf conex cu n = 1 sau n = 2 vrfuri are
n 1 muchii. S presupunem c G are n 3 vrfuri i c toate grafurile ce satisfac relaia (3)
i au mai puin de n vrfuri, satisfac, de asemenea, i relaia |E| |V | 1. Eliminnd o muchie
arbitrar din G, separm graful n k 2 componente conexe. (De fapt k este exact 2). Fiecare
component satisface (3), deoarece, altfel, G nu ar satisface relaia (3). Astfel, prin inducie,
dac adunm numrul muchiilor din fiecare component, obinem cel mult |V | k |V | 2.
Adunnd muchia eliminat, obinem |E| |V | 1.
(4) (5): S presupunem c G este conex i c |E| = |V | 1. Trebuie s artm c G este
aciclic. S presupunem c G posed un ciclu ce conine k vrfuri v1 , v2 , ..., vk . Fie Gk = (Vk , Ek )
subgraful lui G format din ciclul respectiv. Observai c |Vk | = |Ek | = k. Dac k < |V |, atunci,
trebuie s existe un vrf vk+1 V Vk care s fie adiacent unui vrf oarecare vi Vk , din moment
ce G este conex. Definim Gk+1 = (Vk+1 , Ek+1 ) ca fiind subgraful lui G avnd Vk+1 = Vk {vk+1 }
i Ek+1 = Ek {(vi , vk+1 )}. Observai c |Vk+1 | = |Ek+1 | = k+1. Dac k+1 < n putem continua,
definind Gk+2 n aceeai manier, i aa mai departe, pn cnd obinem Gn = (Vn , En ), unde
n = |V |, Vn = V , i |En | = |Vn | = |V |. Deoarece Gn este un subgraf al lui G, avem En E i
de aici |E| |V |, ceea ce contrazice presupunerea c |E| = |V | 1. Astfel, G este aciclic.
(5) (6): S presupunem c G este aciclic i c |E| = |V | 1. Fie k numrul componentelor
conexe ale lui G. Fiecare component conex este, prin definiie, un arbore liber i, deoarece (1)
implic (5), suma tuturor muchiilor din toate componentele conexe ale lui G este |V | k. Prin
urmare, trebuie s avem k = 1 i G este de fapt un arbore. Deoarece (1) implic (2), oricare dou
vrfuri din G sunt conectate printr-un unic drum elementar. Astfel, adugarea oricrei muchii
la G formeaz un ciclu.
(6) (1): S presupunem c G este aciclic, dar c, dac adugm o muchie arbitrar la E,
crem un ciclu. Trebuie s artm c G este conex. Fie u i v dou vrfuri arbitrare din G. Dac
u i v nu sunt deja adiacente, adugnd muchia (u, v), crem un ciclu n care toate muchiile, cu
excepia muchiei (u, v), aparin lui G. Astfel, exist un drum de la u la v i, deoarece u i v au
fost alese arbitrar, G este conex.

5.5.2. Arbori cu rdcin i arbori ordonai


Un arbore cu rdcin este un arbore liber n care unul dintre vrfuri se deosebete de
celelalte. Vrful evideniat se numete rdcina arborelui. De multe ori ne referim la un vrf al
unui arbore cu rdcin ca la un nod2 al arborelui. Figura 5.6(a) prezint un arbore cu radcin
pe o mulime de 12 noduri a crui rdcin este 7.
S lum un nod x ntr-un arbore T care are rdcina r. Orice nod y pe drumul unic din r n
x este numit un strmo al lui x. Dac y este un strmo al lui x, atunci x este un descendent
al lui y. (Fiecare nod este att un strmo ct i un descendent al lui nsui.) Dac y este un
strmo al lui x i x 6= y, atunci y este un strmo propriu al lui x, iar x este un descendent
propriu al lui y. Subarborele cu rdcina x este arborele indus de ctre descendenii lui x
i avnd rdcina x. De exemplu, subarborele avnd ca rdcin nodul 8, din figura 5.6, conine
nodurile 8, 6, 5, i 9.
Dac ultima muchie de pe drumul de la rdcina r a unui arbore T pn la un nod x este
(y, x), atunci y este printele lui x, iar x este un copil al lui y. Rdcina este singurul nod din
2 Termenul de nod este adesea folosit n literatura de teoria grafurilor ca un sinonim pentru vrf. Vom

rezerva folosirea termenului de nod pentru a desemna un vrf al unui arbore cu rdcin.
5.5. Arbori 81

Figura 5.6 Arbori cu rdcin i arbori ordonai. (a) Un arbore cu rdcin avnd nlimea egal
cu 4. Arborele este desenat ntr-un mod standard: rdcina (nodul 7) se afl n partea de sus, copiii ei
(nodurile cu adncimea 1) sub ea, copiii lor (nodurile cu adncimea 2) sub acetia i aa mai departe.
Dac arborele este ordonat, ordinea relativ de la stnga la dreapta a copiilor unui nod este important,
altfel ea nu conteaz. (b) Un alt arbore cu rdcin. Ca arbore cu rdcin, este identic cu cel din (a),
dar privit ca un arbore ordonat el este diferit, din moment ce copiii nodului 3 apar ntr-o ordine diferit.

T fr nici un printe. Dac dou noduri au acelai printe, atunci ele sunt frai. Un nod fr
nici un copil se numete nod extern sau frunz. Un nod care nu este frunz se numete nod
intern.
Numrul copiilor unui nod x dintr-un arbore cu rdcina T se numete gradul lui x.3 Lun-
gimea drumului de la rdcina r la un nod x constituie adncimea lui x n T . Cea mai mare
adncime a unui nod constituie nlimea lui T .
Un arbore ordonat este un arbore cu rdcin n care copiii fiecrui nod sunt ordonai. Cu
alte cuvinte, dac un nod are k copii, atunci exist un prim copil, un al doilea copil,... i un
al k-lea copil. Cei doi arbori din figura 5.6 sunt diferii atunci cnd sunt privii ca fiind arbori
ordonai, dar sunt identici atunci cnd sunt considerai a fi doar arbori cu rdcin.

5.5.3. Arbori binari i arbori poziionali


Arborii binari pot fi descrii cel mai bine ntr-o manier recursiv. Un arbore binar T este
o structur definit pe o mulime finit de noduri care
nu conine nici un nod, sau
este constituit din trei mulimi de noduri disjuncte: un nod rdcin, un arbore binar
numit subarborele stng al su, i un arbore binar numit subarborele drept al lui T .
Arborele binar care nu conine nici un nod se numete arborele vid sau arborele nul, notat
uneori prin nil. Dac subarborele stng nu este vid, atunci rdcina acestuia se numete copilul
3 Observai c gradul unui nod depinde de modul n care este privit T : ca arbore cu rdcin sau ca arbore

liber. Gradul unui vrf dintr-un arbore liber este, ca n orice graf orientat, numrul vrfurilor adiacente lui. Cu
toate acestea, ntr-un arbore cu rdcin, gradul este dat de numrul de copii printele unui nod nu conteaz
din perspectiva gradului.
82 Capitolul 5 Mulimi etc.

Figura 5.7 Arbori binari. (a) Un arbore binar desenat ntr-un mod standard. Copilul stng al unui
nod este desenat dedesubtul nodului i la stnga. Copilul drept este desenat dedesubt i la dreapta.
(b) Un arbore binar diferit de cel din (a). n (a), copilul stng al nodului 7 este 5, iar copilul drept
este absent. n (b), copilul stng al nodului 7 este absent, iar copilul drept este 5. Ca arbori ordonai,
aceti doi arbori sunt identici, dar, privii ca arbori binari, ei sunt diferii. (c) Arborele binar din (a)
reprezentat prin nodurile interne ale unui arbore binar complet: un arbore ordonat n care fiecare nod
intern are gradul 2. Frunzele din arbore sunt reprezentate prin ptrate.

stng al rdcinii ntregului arbore. n mod asemntor, rdcina unui subarbore drept nevid
este copilul drept al rdcinii ntregului arbore. Dac un subarbore este arborele vid nil, copilul
este absent sau lipsete. Figura 5.7(a) prezint un arbore binar.
Un arbore binar nu este un simplu arbore ordonat n care fiecare nod are un grad mai mic sau
egal cu 2. De exemplu, ntr-un arbore binar, dac un nod are doar un copil, poziia copilului
dac este copilul stng sau copilul drept conteaz. ntr-un arbore ordonat, un unic copil nu
poate fi clasificat ca fiind un copil drept sau un copil stng. Figura 5.7(b) prezint un arbore binar
care difer de arborele din figura 5.7(a) din cauza poziiei unui singur nod. Cu toate acestea,
dac sunt privii ca arbori ordonai, cei doi arbori sunt identici.
Informaia poziional dintr-un arbore binar poate fi reprezentat prin nodurile interne ale
unui arbore ordonat, dup cum se arat n figura 5.7(c). Ideea este s nlocuim fiecare copil
absent din arborele binar cu un nod ce nu are nici un copil. Aceste noduri de tip frunz sunt
reprezentate, n figur, prin ptrate. Arborele rezultat este un arbore binar complet: fiecare
nod este fie o frunz, fie are gradul exact 2. Nu exist noduri cu gradul egal cu 1. Prin urmare,
ordinea copiilor unui nod pstreaz informaia poziional.
Informaia poziional care deosebete arborii binari de arborii ordonai poate fi extins i la
arbori cu mai mult de doi copii corespunztori unui nod. ntr-un arbore poziional, copiii unui
nod sunt etichetai cu numere ntregi pozitive distincte. Al i-lea copil al unui nod este absent
dac nici un copil nu este etichetat cu numrul i. Un arbore k-ar este un arbore poziional n
care, pentru fiecare nod, toi copiii cu etichete mai mari dect k lipsesc. Astfel, un arbore binar
este un arbore k-ar cu k = 2.
Un arbore k-ar complet este un arbore k-ar n care toate frunzele au aceeai adncime i
toate nodurile interne au gradul k. Figura 5.8 prezint un arbore binar complet avnd nlimea
egal cu 3. Cte frunze are un arbore k-ar complet de nlime h? Rdcina are k copii de
adncime 1, fiecare dintre acetia avnd k copii de adncime 2 etc. Astfel, numrul frunzelor la
adncimea h este k h . Prin urmare, nlimea unui arbore k-ar complet care are n frunze este
5.5. Arbori 83

Figura 5.8 Un arbore binar complet de nlime 3, cu 8 frunze i 7 noduri interne.

logk n. Numrul nodurilor interne ale unui arbore k-ar complet de nlime h este
h1
X kh 1
1 + k + k 2 + ... + k h1 = ki =
i=0
k1

din ecuaia (3.3). Astfel, un arbore binar complet are 2h 1 noduri interne.

Exerciii
5.5-1 Desenai toi arborii liberi formai din 3 vrfuri A, B, C. Desenai toi arborii cu rdcin
avnd nodurile A, B, C, cu A drept rdcin. Desenai toi arborii ordonai avnd nodurile A,
B, C, cu A drept rdcin. Desenai toi arborii binari avnd nodurile A, B, C, cu A drept
rdcin.
5.5-2 Artai c, pentru n 7, exist un arbore liber cu n noduri astfel nct alegerea fiecruia
din cele n noduri drept rdcin produce un arbore cu rdcin diferit.
5.5-3 Fie G = (V, E) un graf aciclic orientat n care exist un vrf v0 V astfel nct exist un
unic drum de la v0 la fiecare vrf v V . Demonstrai c versiunea neorientat a lui G formeaz
un arbore.
5.5-4 Artai prin inducie c numrul nodurilor cu gradul 2 din orice arbore binar este cu 1
mai mic dect numrul frunzelor.
5.5-5 Artai, prin inducie, c un arbore binar cu n noduri are nlimea cel puin egal cu
blg nc.
5.5-6 ? Lungimea drumului intern al unui arbore binar complet este suma adncimilor tutu-
ror nodurilor interne. n mod asemntor, lungimea drumului exterior este suma adncimilor
tuturor frunzelor. Se d un arbore binar complet cu n noduri interne, avnd lungimea drumului
interior i i lungimea drumului exterior e. Demonstrai c e = i + 2n.
5.5-7 ? AsociemPun cost w(x) = 2d fiecrei frunze x de adncime d dintr-un arbore binar T .
Demonstrai c x w(x) 1, unde x este orice frunz din T . (Aceast relaie este cunoscut
sub numele de inegalitatea Kraft.)
5.5-8 ? Artai c orice arbore binar cu L frunze conine un subarbore avnd ntre L/3 i 2L/3
frunze (inclusiv).
84 Capitolul 5 Mulimi etc.

Probleme
5-1 Colorarea grafurilor
O k-colorare a unui graf neorientat G = (V, E) este o funcie c : V {0, 1, ..., k 1} astfel nct
c(u) 6= c(v) pentru orice muchie (u, v) E. Cu alte cuvinte, numerele 0, 1, ..., k 1 reprezint k
culori, iar nodurile adiacente trebuie s aib culori diferite.
a. Demonstrai c orice arbore este 2-colorabil.
b. Artai c urmtoarele afirmaii sunt echivalente:
(a) G este bipartit.
(b) G este 2-colorabil.
(c) G nu are cicluri de lungime impar.
c. Fie d gradul maxim al oricrui vrf dintr-un graf G. Artai c G poate fi colorat cu d + 1
culori.
p
d. Artai c dac G are O(|V |) muchii, atunci G poate fi colorat cu O( |V |) culori.

5-2 Grafuri de prieteni


Reformulai fiecare dintre urmtoarele afirmaii sub forma unei teoreme despre grafuri neori-
entate, iar apoi demonstrai teorema. Putei presupune c prietenia este simetric dar nu i
reflexiv.
a. n orice grup de n 2 persoane, exist dou persoane cu acelai numr de prieteni n grup.
b. Orice grup de ase persoane conine fie trei persoane ntre care exist o relaie de prietenie
reciproc, fie trei persoane care nu se cunosc nici una pe cealalt.
c. Orice grup de persoane poate fi mprit n dou subgrupuri astfel nct cel puin jumtate
din prietenii fiecrei persoane s se afle n grupul din care persoana respectiv nu face
parte.
d. Dac toate persoanele dintr-un grup sunt prietene cu cel puin jumtate din persoanele
din grup, atunci grupul poate fi aezat la o mas astfel nct fiecare persoan este aezat
ntre doi prieteni.

5-3 mprirea arborilor n dou


Muli algoritmi divide i stpnete care lucreaz pe grafuri cer ca graful s fie mparit n dou
subgrafuri de dimensiuni aproximativ egale, prin eliminarea unui mic numr de muchii. Aceast
problem cerceteaz mprirea n dou a arborilor.
a. Demonstrai c, prin eliminarea unei singure muchii, putem partiiona vrfurile oricrui
arbore binar avnd n vrfuri n dou mulimi A i B astfel nct |A| 3n/4 i |B| 3n/4.
b. Demonstrai c aceast constant de 3/4 de la punctul (a) este optimal n cel mai
defavorabil caz, dnd un exemplu de arbore simplu a crui cea mai echilibrat partiie,
dup eliminarea unei singure muchii, are proprietatea |A| = 3n/4.
Note bibliografice 85

c. Demonstrai c, prin eliminarea a cel mult O(lg n) muchii, putem partiiona vrfurile
oricrui arbore avnd n vrfuri n dou mulimi A i B astfel nct |A| = bn/2c i
|B| = dn/2e.

Note bibliografice
G. Boole a dus o munc de pionierat n dezvoltarea logicii simbolice i a introdus multe dintre
notaiile de baz pentru mulimi ntr-o carte publicat n 1854. Teoria modern a mulimilor
a fost elaborat de ctre G. Cantor n timpul perioadei 18741895. Cantor s-a concentrat, n
special, asupra mulimilor cu cardinalitate infinit. Termenul de funcie este atribuit lui G. W.
Leibnitz, care l-a folosit pentru a se referi la mai multe feluri de formule matematice. Definiia sa
limitat a fost generalizat de multe ori. Teoria grafurilor dateaz din anul 1736, cnd L. Euler
a demonstrat c este imposibil ca o persoan s traverseze fiecare din cele 7 poduri din oraul
Knigsberg exact o singur dat i s se ntoarc n locul de unde a plecat.
Un compendiu folositor, coninnd mai multe definiii i rezultate din teoria grafurilor, se
afl n cartea scris de Harary [94].
6 Numrare i probabilitate

n acest capitol trecem n revist combinatorica elementar i teoria elementar a probabili-


tilor. Dac avei o bun fundamentare n aceste domenii, putei trece mai uor peste nceputul
capitolului i s v concentrai asupra seciunilor urmtoare. Multe dintre capitole nu necesit
probabiliti, dar pentru anumite capitole ele sunt eseniale.
n seciunea 6.1 trecem n revist principalele rezultate ale teoriei numrrii (combinatori-
ca, analiza combinatorie), inclusiv formule standard pentru numrarea permutrilor i combi-
nrilor. n seciunea 6.2 sunt prezentate axiomele probabilitii i rezultatele de baz legate de
distribuiile de probabilitate. Variabilele aleatoare sunt introduse n seciunea 6.3, unde se dau de
asemenea proprietile mediei i ale dispersiei. Seciunea 6.4 investigheaz distribuia geometric
i cea binomial care apar n studiul probelor bernoulliene. Studiul distribuiei binomiale este
continuat n seciunea 6.5, care este o discuie avansat despre cozile distribuiei. n fine, n
seciunea 6.6 ilustrm analiza probabilistic prin intermediul a trei exemple: paradoxul zilei de
natere, aruncarea aleatoare a bilelor n cutii i ctigarea liniilor (secvenelor).

6.1. Numrare
Teoria numrrii ncearc s rspund la ntrebarea ci, fr a numra efectiv. De exemplu,
am putea s ne ntrebm cte numere distincte de n bii exist, sau n cte moduri pot fi
ordonate n elemente distincte. n aceast seciune, vom trece n revist elementele teoriei nu-
mrrii. Deoarece anumite pri ale materialului necesit nelegerea noiunilor i rezultatelor
de baz referitoare la mulimi, cititorul este sftuit s nceap prin a revedea materialul din
seciunea 5.1.

Regulile sumei i produsului


O mulime ale crei elemente dorim s le numrm poate fi exprimat uneori ca o reuniune
de mulimi disjuncte sau ca un produs cartezian de mulimi.
Regula sumei ne spune c numrul de moduri de alegere a unui element din cel puin una
din dou mulimi disjuncte este suma cardinalilor mulimilor. Altfel spus, dac A i B sunt dou
mulimi finite fr nici un element comun, atunci |A B| = |A| + |B|, ceea ce rezult din ecuaia
(5.3). De exemplu, fiecare poziie de pe un numr de main este o liter sau o cifr. Numrul de
posibiliti, pentru fiecare poziie, este 26 + 10 = 36 deoarece sunt 26 de alegeri pentru o liter
i 10 alegeri pentru o cifr.
Regula produsului spune c numrul de moduri n care putem alege o pereche ordonat
este numrul de alegeri pentru primul element nmulit cu numrul de alegeri pentru al doilea
element. Adic, dac A i B sunt dou mulimi finite, atunci |A B| = |A| |B|, care este, pur
i simplu, ecuaia (5.4). De exemplu, dac un productor de ngheat ofer 28 de arome de
ngheat i 4 tipuri de glazuri, numrul total de sortimente cu un glob de ngheat i o glazur
este 28 4 = 112.
6.1. Numrare 87

iruri
Un ir peste o mulime finit S este o secven de elemente din S. De exemplu, exist 8
iruri binare de lungime 3:

000, 001, 010, 011, 100, 101, 110, 111.

Vom numi, uneori, k-ir un ir de lungime k. Un subir s0 al unui ir s este o secven ordo-
nat de elemente consecutive ale lui s. Un k-subir al unui ir este un subir de lungime k. De
exemplu, 010 este un 3 subir al lui 01101001 (3-subirul care ncepe din poziia 4), dar 111 nu
este un subir al lui 01101001.
Un k-ir peste o mulime S poate fi privit ca un element al produsului cartezian S k de k-tuple;
astfel exist |S|k iruri de lungime k. De exemplu, numrul de k-iruri binare este 2k . Intuitiv,
pentru a construi k-iruri peste o mulime de n elemente (n-mulime), avem n moduri de alegere
pentru primul element; pentru fiecare dintre aceste alegeri, avem n moduri de a alege al doilea
element; i aa mai departe de k ori. Aceast construcie ne conduce la concluzia c numrul de
k-iruri este produsul a k factori identici n n n = nk .

Permutri
O permutarea unei mulimi finite S este o secven ordonat a tuturor elementelor lui S, cu
fiecare element aprnd exact o singur dat. De exemplu, dac S = {a, b, c}, exist 6 permutri
ale lui S:

abc, acb, bac, bca, cab, cba.

Exist n! permutri ale unei mulimi avnd n elemente, deoarece primul element al secvenei
poate fi ales n n moduri, al doilea n n 1 moduri, al treilea n n 2 moduri .a.m.d.
O k-permutare 1 a lui S este o secven de k elemente ale lui S n care nici un element
nu apare mai mult de o singur dat. (Astfel o permutare ordinar este o n-permutare a unei
n-mulimi.) Cele dousprezece 2-permutri ale mulimii {a, b, c, d} sunt

ab, ac, ad, ba, bc, bd, ca, cb, cd, da, db, dc.

Numrul de k-permutri ale unei n-mulimi este


n!
n(n 1)(n 2) (n k + 1) = , (6.1)
(n k)!
deoarece exist n moduri de a alege primul element, n 1 moduri de a alege al doilea element
i tot aa, pn se selecteaz k elemente, ultimul fiind o selecie de n k + 1 elemente.

Combinri
O k-combinare a unei n-mulimi S este, pur i simplu, o k-submulime a lui S. Exist ase
2-combinri ale unei 4-mulimi {a, b, c, d}:

ab, ac, ad, bc, bd, cd.


1 sau aranjament n.t.
88 Capitolul 6 Numrare i probabilitate

(Aici am utilizat prescurtarea ab pentru a nota mulimea {a, b} .a.m.d.) Putem construi o
k-combinare a unei n-mulimi alegnd k elemente diferite (distincte) din n-mulime.
Numrul de k-combinri ale unei n-mulimi poate fi exprimat cu ajutorul numrului de k-
permutri ale unei n-mulimi. Pentru orice k-combinare, exist exact k! permutri ale elementelor
sale, fiecare fiind o k-permutare distinct a n-mulimii. Astfel, numrul de k-combinri ale unei
n-mulimi este numrul de k-permutri mprit cu k!; din ecuaia (6.1), aceast valoare este
n!
. (6.2)
k!(n k)!
Pentru k = 0, aceast formul ne spune c numrul de moduri n care putem alege 0 elemente
dintr-o n-mulime este 1 (nu 0), deoarece 0! = 1.

Coeficieni binomiali

Vom utiliza notaia nk (se citete combinri de n luate cte k) pentru a desemna numrul
de k-combinri ale unei n-mulimi. Din ecuaia (6.2) avem

n n!
= . (6.3)
k k!(n k)!
Aceast formul este simetric n k i n k:

n n
= . (6.4)
k nk
Aceste numere sunt cunoscute i sub numele de coeficieni binomiali deoarece apar n dez-
voltarea binomial (formula binomului lui Newton):
n
X
n n k nk
(x + y) = x y . (6.5)
k
k=0

Un caz special al dezvoltrii binomiale este acela n care x = y = 1:


Xn
n n
2 = . (6.6)
k
k=0

Aceast formul corespunde


n numrrii celor 2n n-iruri binare dup numrul de cifre 1 pe care
ele l conin: exist k iruri binare ce conin exact k de 1 deoarece exist nk moduri de a alege
k din cele n poziii n care vom pune cifre 1.
Exist multe identiti referitoare la coeficienii binomiali. Exerciiile de la sfritul acestei
seciuni v ofer posibilitatea s demonstrai cteva.

Margini binomiale
Uneori, avem nevoie s delimitm mrimea unui coeficient binomial. Pentru 1 k n, avem
marginea inferioar

n n(n 1) (n k + 1) n n 1 nk+1 n k
= = . (6.7)
k k(k 1) 1 k k1 1 k
6.1. Numrare 89

Utiliznd inegalitatea k! (k/e)k , dedus din formula lui Stirling (2.12), obinem marginea
superioar

n n(n 1) (n k + 1) nk
= (6.8)
k k(k 1) 1 k!
en k
. (6.9)
k
Pentru orice 0 k n, putem utiliza inducia (vezi exerciiul 6.1-12) pentru a demonstra
delimitarea

n nn
k , (6.10)
k k (n k)nk

unde, pentru comoditate, am presupus c 00 = 1. Pentru k = n, unde 0 1, aceast


margine se poate rescrie sub forma
1 !n

n nn 1 1
n (1)n
= (6.11)
n (n) ((1 )n) 1
= 2nH() , (6.12)

unde

H() = lg (1 ) lg(1 ) (6.13)

este funcia entropie (binar) i unde, pentru comoditate, am presupus c 0 lg 0 = 0, astfel


c H(0) = H(1) = 0.

Exerciii
6.1-1 Cte k-subiruri are un n-ir? (Considerm k-subirurile identice ce apar pe poziii diferite
ca fiind diferite.) Cte subiruri are n total un n-ir?

6.1-2 O funcie boolean avnd n intrri i m ieiri este o funcie de la {adevrat, fals}n
la {adevrat, fals}m . Cte funcii booleene avnd n intrri i o ieire exist? Cte funcii
booleene avnd n intrri i m ieiri exist?

6.1-3 n cte moduri se pot aeza n profesori n jurul unei mese circulare la o conferin?
Considerm c dou aezri sunt identice dac una poate fi rotit pentru a o obine pe cealalt.

6.1-4 n cte moduri pot fi alese trei numere distincte din mulimea {1, 2, . . . , 100} astfel ca
suma lor s fie par?

6.1-5 Demonstrai identitatea:



n n n1
= (6.14)
k k k1
pentru 0 < k n.
90 Capitolul 6 Numrare i probabilitate

6.1-6 Demonstrai identitatea:



n n n1
=
k nk k

pentru 0 k < n.

6.1-7 Pentru a alege k obiecte din n, putei marca unul dintre obiecte i s vedei dac a fost
ales obiectul marcat. Utilizai aceast abordare pentru a demonstra c

n n1 n1
= + .
k k k1

6.1-8 Utiliznd rezultatul din exerciiul 6.1-7, construii o tabel a coeficienilor binomiali, nk
0 1 1
pentru n = 0, 1, . . . , 6 i 0 k n, cu 0 n vrf, 0 i 1 pe linia urmtoare i aa mai
departe. O astfel de tabel de coeficieni binomiali se numete triunghiul lui Pascal .

6.1-9 Demonstrai c
n
X
n+1
i= .
i=1
2

n
6.1-10 Artai c, pentru orice n 0 i 0 k n, maximul valorii lui k se realizeaz cnd
k = bn/2c sau k = dn/2e.

6.1-11 ? Argumentai c, pentru orice n 0, j 0, k 0 i j + k n,



n n nj
. (6.15)
j+k j k

Dai att o demonstraie algebric ct i una bazat pe o metod de alegere a celor j +k elemente
din n. Dai un exemplu n care egalitatea s nu aib loc.

6.1-12 ? Utilizai inducia dup k n/2 pentru a demonstra inegalitatea (6.10) i utilizai
ecuaia (6.4) pentru a o extinde pentru orice k n.

6.1-13 ? Utilizai aproximaia lui Stirling pentru a demonstra c



2n 22n
= (1 + O(1/n)) . (6.16)
n n

6.1-14 ? Derivnd funcia entropie H(), artai c ea i atinge valoarea maxim n = 1/2.
Ct este H(1/2)?
6.2. Probabilitate 91

6.2. Probabilitate
Probabilitatea este un instrument esenial pentru proiectarea i analiza algoritmilor pur pro-
babiliti i a algoritmilor care se bazeaz pe generarea de numere aleatoare. n aceast seciune,
se trec n revist bazele teoriei probabilitilor.
Vom defini probabilitatea n termeni de spaiu de selecie S, care este o mulime ale crei
elemente se numesc evenimente elementare. Fiecare eveniment elementar poate fi privit ca
un rezultat posibil al unui experiment. Pentru experimentul aruncrii a dou monede distincte
i distinctibile, putem privi spaiul de selecie ca fiind mulimea tuturor 2-irurilor peste {s, b}:

S = {ss, sb, bs, bb}.

Un eveniment este o submulime2 a spaiului de selecie S. De exemplu, n experimentul


aruncrii a dou monede, evenimentul de a obine un ban sau o stem este {sb,bs}. Evenimentul
S se numete eveniment sigur , iar evenimentul se numete eveniment nul sau eveniment
imposibil . Spunem c dou evenimente sunt mutual exclusive sau incompatibile dac A
B = . Vom trata, uneori, un eveniment elementar s S ca fiind evenimentul {s}. Prin definiie,
toate evenimentele elementare sunt mutual exclusive.

Axiomele probabilitii
O distribuie de probabilitate (probabilitate) Pr{} pe spaiul de selecie S este o aplicaie
de la mulimea evenimentelor lui S la mulimea numerelor reale care satisface urmtoarele
axiome ale probabilitii :

1. Pr{A} 0 pentru orice eveniment A.

2. Pr{S} = 1.

3. Pr{A B} = Pr{A} + Pr{B} pentru oricare dou evenimente mutual exclusive A i B.


Mai general, pentru orice secven (finit sau infinit numrabil) de evenimente A1 , A2 , . . .
care sunt dou cte dou mutual exclusive
( )
[ X
Pr Ai = Pr{Ai }.
i i

Vom numi Pr{A} probabilitatea evenimentului A. De notat c axioma 2 este o cerin de


normalizare: nu este nimic fundamental n alegerea lui 1 ca probabilitate a evenimentului sigur,
exceptnd faptul c este mai natural i mai convenabil.
2 Pentru o distribuie de probabilitate general, pot exista anumite submulimi ale lui S care nu sunt considerate

evenimente. Aceast situaie apare de obicei cnd spaiul de selecie este infinit nenumrabil. Cerina principal
este ca mulimea evenimentelor din spaiul de selecie s fie nchis la operaiile de complementare i la intersecia
unui numr finit sau numrabil de evenimente. Cele mai multe dintre distribuiile pe care le vom ntlni sunt
definite peste spaii de selecie finite sau numrabile i vom considera toate submulimile spaiului de selecie ca
fiind evenimente. O excepie notabil va fi distribuia de probabilitate uniform continu, pe care o vom prezenta
pe scurt.
92 Capitolul 6 Numrare i probabilitate

Anumite rezultate se pot deduce imediat din aceste axiome i din rezultatele de baz ale
teoriei mulimilor (vezi seciunea 5.1). Evenimentul nul are probabilitatea Pr{} = 0. Dac
A B, atunci Pr{A} Pr{B}. Utiliznd A pentru a nota evenimentul S A (complementul
sau evenimentul contrar lui A), avem Pr{A} = 1 Pr{A}. Pentru oricare dou evenimente
A i B,

Pr{A B} = Pr{A} + Pr{B} Pr{A B} (6.17)


Pr{A} + Pr{B}. (6.18)

n exemplul nostru cu aruncarea monedei presupunem c fiecare eveniment elementar are pro-
babilitatea 1/4. Probabilitatea de a obine cel puin o stem este

Pr{ss, sb, bs} = Pr{ss} + Pr{sb} + Pr{bs} = 3/4.

Altfel, deoarece probabilitatea de a obine mai puin de o stem este Pr{bb} = 1/4, probabili-
tatea de a obine cel puin o stem este 1 1/4 = 3/4.

Distribuii discrete de probabilitate


O distribuie de probabilitate este discret dac este definit peste un spaiu de selecie
finit sau numrabil. Fie S spaiul de selecie. Atunci pentru orice eveniment A,
X
Pr{A} = Pr{s},
sA

deoarece evenimentele elementare, mai concret cele din A, sunt mutual exclusive. Dac S este
finit i fiecare eveniment elementar s S are probabilitatea

Pr{s} = 1/|S|,

atunci avem distribuia de probabilitate uniform 3 pe S. ntr-un astfel de caz, experimentul


este descris adesea ca alegerea unui element al lui S la ntmplare.
De exemplu, s considerm procesul de aruncare a unei monede perfecte (corecte, ideale),
pentru care probabilitatea de a obine stema este aceeai cu probabilitatea de a obine banul,
adic 1/2. Dac aruncm moneda de n ori, avem distribuia de probabilitate uniform definit
peste spaiul de selecie S = {s, b}n , o mulime de dimensiune (cardinal) 2n . Fiecare element
din S poate fi reprezentat ca un ir de lungime n peste {s, b} i fiecare apare cu probabilitatea
1/2n . Evenimentul

A = {stema apare de exact k ori i banul apare de n k ori}



este o submulime a lui S, de dimensiune (cardinal) |A| = nk deoarece exist nk iruri de
lungime n peste {s, b} ce conin exact k s-uri. Astfel probabilitatea lui A este Pr{A} = nk /2n .

3 distribuia uniform discret pe S n.t.


6.2. Probabilitate 93

Distribuia de probabilitate uniform continu


Distribuia de probabilitate uniform continu este un exemplu de distribuie de probabilitate
n care nu toate submulimile spaiului de selecie sunt considerate evenimente. Distribuia de
probabilitate uniform continu este definit pe un interval nchis [a, b] al axei reale, cu a < b.
Intuitiv, dorim ca toate punctele intervalului [a, b] s fie echiprobabile. Exist, totui, o infinitate
nenumrabil de puncte, aa c, dac atribuim tuturor punctelor aceeai probabilitate finit,
pozitiv, nu putem satisface axiomele 2 i 3. Din acest motiv, vom asocia o probabilitate numai
anumitor submulimi ale lui S, astfel ca axiomele s fie satisfcute pentru astfel de evenimente.
Pentru orice interval nchis [c, d], unde a c d b, distribuia de probabilitate
uniform continu definete probabilitatea evenimentului [c, d] ca fiind
dc
Pr{[c, d]} = .
ba
De notat c, pentru orice punct x = [x, x], probabilitatea lui x este 0. Dac nlturm capetele
unui interval [c, d], obinem un interval deschis (c, d). Deoarece [c, d] = [c, c](c, d)[d, d], pe baza
axiomei 3 avem Pr{[c, d]} = Pr{(c, d)}. n general, mulimea evenimentelor pentru distribuia
de probabilitate uniform continu este constituit din toate submulimile lui [a, b] care pot fi
obinute printr-o reuniune finit de intervale deschise sau nchise.

Probabilitate condiionat i independen


Uneori avem, cu anticipaie, unele cunotine pariale despre un experiment. De exemplu, s
presupunem c un prieten a aruncat dou monede perfecte i c v-a spus c cel puin una din
ele a artat stema. Care este probabilitatea s obinem dou steme? Informaia dat elimin
posibilitatea de a avea de dou ori banul. Cele trei evenimente care au rmas sunt echiprobabile,
deci deducem c fiecare din ele apare cu probabilitatea 1/3. Deoarece numai unul dintre acestea
nseamn dou steme, rspunsul la ntrebarea noastr este 1/3.
Probabilitatea condiionat formalizeaz noiunea de a avea cunotine pariale despre rezul-
tatul unui experiment. Probabilitea condiionat a evenimentului A, tiind c un alt eveni-
ment B a aprut, se definete prin
Pr{A B}
Pr{A|B} = , (6.19)
Pr{B}
ori de cte ori Pr{B} 6= 0. (Notaia Pr{A|B} se va citi probabilitatea lui A condiionat de B.)
Intuitiv, deoarece se d c evenimentul B a aprut, evenimentul ca A s apar, de asemenea
este A B. Adic, A B este mulimea rezultatelor n care apar att A ct i B 4 . Deoarece
rezultatul este unul din evenimentele elementare ale lui B, normalizm probabilitile tuturor
evenimentelor elementare din B, mprindu-le la Pr{B}, astfel ca suma lor s fie 1. Probabilita-
tea lui A condiionat de B este, de aceea, raportul dintre probabilitatea evenimentului A B i
probabilitatea lui B. n exemplul de mai sus, A este evenimentul ca ambele monede s dea stema,
iar B este evenimentul ca s se obin cel puin o stem. Astfel, Pr{A|B} = (1/4)/(3/4) = 1/3.
Dou evenimente sunt independente dac

Pr{A B} = Pr{A} Pr{B},


4 Elementele lor sau rezultatele lor n.t.
94 Capitolul 6 Numrare i probabilitate

ceea ce este echivalent, dac Pr{B} 6= 0, cu condiia


Pr{A|B} = Pr{A}.
De exemplu, s presupunem c se arunc dou monede perfecte i c rezultatele sunt indepen-
dente. Atunci probabilitatea de a obine dou steme este (1/2)(1/2) = 1/4. Presupunem acum
c un eveniment este ca prima moned s dea o stem i cel de-al doilea este ca monedele s dea
rezultate diferite. Fiecare dintre aceste evenimente apare cu probabilitatea 1/2, iar probabilitatea
ca s apar ambele evenimente este 1/4; astfel, conform definiiei independenei, evenimentele
sunt independente chiar dac ne-am putea gndi c ambele depind de prima moned. n fine,
s presupunem c monedele sunt legate, astfel nct pe ambele s cad fie stema, fie banul i c
ambele posibiliti sunt egal probabile. Atunci probabilitatea ca fiecare moned s dea stema este
1/2, dar probabilitatea ca ambele s dea stema este 1/2 6= (1/2)(1/2). n consecin, evenimentul
ca o moned s dea stema i evenimentul ca cealalt s dea stema nu sunt independente.
O colecie de evenimente A1 , A2 , . . . , An se numete independent pe perechi (sau spunem
c evenimentele sunt dou cte dou independente n.t.) dac
Pr{Ai Aj } = Pr{Ai } Pr{Aj }
pentru orice 1 i < j n. Spunem c evenimentele A1 , . . . , An sunt (mutual ) independente
(sau independente n totalitate) dac fiecare k-submulime Ai1 , Ai2 , . . . , Aik a coleciei, unde
2 k n i 1 i1 < i2 < . . . < ik n satisface
Pr{Ai1 Ai2 . . . Aik } = Pr{Ai1 } Pr{Ai2 } . . . Pr{Aik }.
De exemplu, s presupunem c aruncm dou monede perfecte. Fie A1 evenimentul ca prima
moned s dea stema, fie A2 evenimentul ca a doua moned s dea stema i A3 evenimentul ca
cele dou monede s fie diferite. Avem
Pr{A1 } = 1/2,
Pr{A2 } = 1/2,
Pr{A3 } = 1/2,
Pr{A1 A2 } = 1/4,
Pr{A1 A3 } = 1/4,
Pr{A2 A3 } = 1/4,
Pr{A1 A2 A3 } = 0.
Deoarece pentru 1 i < j 3, avem Pr{Ai Aj } = Pr{Ai } Pr{Aj } = 1/4, evenimentele
A1 , A2 i A3 sunt dou cte dou independente. Ele nu sunt mutual independente, deoarece
Pr{A1 A2 A3 } = 0 i Pr{A1 } Pr{A2 } Pr{A3 } = 1/8 6= 0.

Teorema lui Bayes


Din definiia probabilitii condiionate (6.19) rezult c, pentru dou evenimente A i B,
fiecare cu probabilitate nenul, avem
Pr{A B} = Pr{B} Pr{A|B} = P r{A} Pr{B|A} (6.20)
Exprimnd din ecuaiile de mai sus Pr{A|B}, obinem
Pr{A} Pr{B|A}
Pr{A|B} = , (6.21)
Pr{B}
6.2. Probabilitate 95

relaie care este cunoscut sub numele de teorema lui Bayes. Numrtorul Pr{B} este o
constant de normalizare pe care o putem rescrie dup cum urmeaz. Deoarece B = (B A)
(B A) i B A i B A sunt mutual exclusive,
= Pr{A} Pr{B|A} + Pr{A}
Pr{B} = Pr{B A} + Pr{B A} Pr{B|A}.

nlocuind n ecuaia (6.21), obinem o form echivalent a teoremei lui Bayes:


Pr{A} Pr{B|A}
Pr{A|B} = .
Pr{B|A}
Pr{A} Pr{B|A} + Pr{A}
Teorema lui Bayes poate uura calculul probabilitilor condiionate. De exemplu, s presupunem
c avem o moned perfect i o moned fals care cade ntotdeauna pe stem. Efectum un
experiment ce const din trei evenimente independente: una dintre cele dou monede este aleas
la ntmplare, aruncat o dat i apoi aruncat din nou. S presupunem c moneda aleas a dat
stema la ambele aruncri. Care este probabilitatea ca ea s fie fals?
Vom rezolva aceast problem utiliznd teorema lui Bayes. Fie A evenimentul ca s fie aleas
moneda fals i fie B evenimentul ca moneda s ne dea de dou ori stema. Dorim s determinm
Pr{A|B}. Avem Pr{A} = 1/2, Pr{B|A} = 1, Pr{A} = 1/2 i Pr{B|A} = 1/4; deci

(1/2) 1
Pr{A|B} = = 4/5.
(1/2) 1 + (1/2) (1/4)

Exerciii
6.2-1 Demonstrai inegalitatea lui Boole: pentru orice secven finit sau infinit numrabil
de evenimente A1 , A2 , . . .
Pr{A1 A2 . . .} Pr{A1 } + Pr{A2 } + . (6.22)

6.2-2 Profesorul Rosencrantz arunc o moned perfect. Profesorul Guildenstern arunc dou
monede perfecte. Care este probabilitatea ca profesorul Rosencrantz s obin mai multe steme
dect profesorul Guildenstern?

6.2-3 Un pachet de 10 cri, fiecare coninnd un numr distinct de la 1 la 10, este amestecat
bine. Se extrag trei cri din pachet, cte una la un moment dat. Care este probabilitatea ca cele
trei cri selectate s fie sortate (cresctor)?

6.2-4 ? Se d o moned fals, care, atunci cnd este aruncat, produce stema cu o probabilitate
p (necunoscut), unde 0 < p < 1. Artai cum poate fi simulat o aruncare de moned perfec-
t examinnd aruncri multiple. (Indicaie: aruncai moneda de dou ori i apoi fie returnai
rezultatul, fie repetai experimentul.) Demonstrai c rspunsul este corect.

6.2-5 ? Descriei o procedur are accept, la intrare, doi ntregi a i b, astfel nct 0 < a < b i,
utiliznd aruncri de monede perfecte producei, la ieire, stema cu probabilitatea a/b i banul
cu probabilitatea (ba)/b. Dai o margine a numrului mediu de aruncri de monede, care poate
fi un polinom n lg b.

6.2-6 Demonstrai c

Pr{A|B} + Pr{A|B} = 1.
96 Capitolul 6 Numrare i probabilitate

6.2-7 Artai c, pentru orice colecie de evenimente A1 , A2 , . . . , An ,


Pr{A1 A2 . . . An } =
Pr{A1 } Pr{A2 |A1 } Pr{A3 |A1 A2 } Pr{An |A1 A2 . . . An1 }.

6.2-8 ? Artai cum se poate construi o mulime de n evenimente care s fie dou cte dou
independente, dar orice submulime de k > 2 dintre ele s nu fie mulime de evenimente mutual
independente.

6.2-9 ? Dou evenimente A i B sunt independente condiionat dac


Pr{A B|C} = Pr{A|C} Pr{B|C},
unde C este dat. Dai un exemplu simplu, dar netrivial, de dou evenimente care nu sunt
independente, dar care sunt independente condiionat, fiind dat un al treilea eveniment.

6.2-10 ? Suntei concurent ntr-un joc-spectacol n care un premiu este ascuns n spatele uneia
dintre trei cortine. Vei ctiga premiul dac alegei cortina corect. Dup ce ai ales cortina,
dar nainte ca ea s fie ridicat, prezentatorul ridic una dintre celelalte cortine, artnd o scen
goal i v ntreab dac dorii s v schimbai opiunea curent pentru cortina rmas. Care
va fi ansa dumneavoastr dac v schimbai opiunea?

6.2-11 ? Un director al unei nchisori a ales aleator un prizonier din trei pentru a fi eliberat.
Ceilali doi vor fi executai. Gardianul tie care va fi liber, dar i este interzis s dea oricrui
prizonier informaii referitoare la starea acestuia. S numim cei trei prizonieri X, Y i Z.
Prizonierul X ntreab gardianul, n particular, care dintre Y i Z vor fi executai, argumentnd
c, dac cel puin unul dintre cei doi trebuie s moar, gardianul nu-i d nici o informaie despre
starea sa. Gardianul i spune lui X c Y va fi executat. Prizonierul X se simte mai fericit acum,
deoarece sau el sau Z va fi liber, ceea ce nseamn c probabilitatea ca el s fie liber este acum
1/2. Are dreptate, sau ansa sa este tot 1/3? Explicai.

6.3. Variabile aleatoare discrete


O variabil aleatoare (discret) X este o funcie de la un spaiu de selecie S, finit sau
infinit numrabil, la mulimea numerelor reale. Ea asociaz un numr real fiecrui rezultat al
unui experiment, ceea ce ne permite s lucrm cu distribuia de probabilitate indus de mulimea
de numere rezultat. Variabilele aleatoare pot fi definite i pentru spaii de selecie nenumrabile,
dar se ajunge la probleme tehnice a cror rezolvare nu este necesar pentru scopurile noastre.
De aceea, vom presupune c variabilele aleatoare sunt discrete.
Pentru o variabil aleatoare X i un numr real x, definim evenimentul X = x ca fiind
{s S : X(s) = x}; astfel
X
Pr{X = x} = Pr{s}.
{sS:X(s)=x}

Funcia
f (x) = Pr{X = x}
6.3. Variabile aleatoare discrete 97

este densitatea
P de probabilitate 5 a variabilei aleatoare X. Din axiomele probabilitii, Pr{X =
x} 0 i x Pr{X = x} = 1.
De exemplu, s considerm experimentul aruncrii unei perechi de zaruri obinuite, cu 6 fee.
Exist 36 de evenimente elementare posibile n spaiul de selecie. Presupunem c distribuia de
probabilitate este uniform, astfel c fiecare eveniment elementar s S are aceeai probabilitate:
Pr{s} = 1/36. Definim variabila aleatoare X ca fiind maximul celor dou valori de pe feele
zarurilor. Avem Pr{X = 3} = 5/36, deoarece X atribuie valoarea 3 la 5 din cele 36 de evenimente
elementare posibile i anume (1,3), (2,3), (3,3), (3,2) i (3,1).
Se obinuiete ca mai multe variabile aleatoare s fie definite pe acelai spaiu de selecie.
Dac X i Y sunt variabile aleatoare, funcia
f (x, y) = Pr{X = x i Y = y}
este funcia densitate de probabilitate asociat lui X i Y . Pentru o valoare fixat y,
X
Pr{Y = y} = Pr{X = x i Y = y}
x

i la fel, pentru o valoare fixat x


X
Pr{X = x} = Pr{X = x i Y = y}.
y

Utiliznd definiia (6.19) a probabilitii condiionate, avem


Pr{X = x i Y = y}
Pr{X = x|Y = y} = .
Pr{Y = y}
Spunem c dou variabile aleatoare X i Y sunt independente dac, pentru orice x i y,
evenimentele X = x i Y = y sunt independente, sau echivalent, dac, pentru orice x i y, avem
Pr{X = x i Y = y} = Pr{X = x} Pr{Y = y}.
Dndu-se o mulime de variabile aleatoare peste acelai spaiu de selecie, se pot defini noi
variabile aleatoare, cum ar fi suma, produsul sau alte funcii de variabilele originale.

Valoarea medie a unei variabile aleatoare


Cea mai simpl i mai util descriere a distribuiei unei variabile aleatoare este media
valorilor pe care le ia. Valoarea medie (sau sinonim sperana sau media) a unei variabile
aleatoare discrete X este
X
E[X] = x Pr{X = x}, (6.23)
x

care este bine definit dac suma este finit sau absolut convergent. Uneori media se noteaz
cu X , sau cnd variabila aleatoare este subneleas din context cu .
S considerm un joc n care se arunc dou monede perfecte. Ctigai 3$ pentru fiecare
stem i pierdei 2$ pentru fiecare ban. Valoarea medie a variabilei aleatoare X ce reprezint
ctigul dumneavoastr este
E[X] = 6 Pr{2s} + 1 Pr{1s,1b} 4 Pr{2b} = 6(1/4) + 1(1/2) 4(1/4) = 1.
5 termenul corect din punctul de vedere al teoriei probabilitailor este funcie de mas sau funcie de

frecven n.t.
98 Capitolul 6 Numrare i probabilitate

Media sumei a dou variabile aleatoare este suma mediilor, adic

E[X + Y ] = E[X] + E[Y ], (6.24)

ori de cte ori E[X] i E[Y ] sunt definite. Aceast proprietate se extinde la sume finite i absolut
convergente de medii.
Dac X este o variabil aleatoare, orice funcie g(x) definete o nou variabil aleatoare g(X).
Dac valoarea medie a lui g(X) este definit, atunci
X
E[g(X)] = g(x) Pr{X = x}.
x

Lund g(x) = ax, avem pentru orice constant

E[aX] = aE[X]. (6.25)

n consecin, mediile sunt liniare: pentru oricare dou variabile aleatoare X i Y i orice
constant a,

E[aX + Y ] = aE[X] + E[Y ]. (6.26)

Cnd dou variabile aleatoare X i Y sunt independente i media fiecreia este definit, avem
XX XX
E[XY ] = xy Pr{X = x i Y = y} = xy Pr{X = x} Pr{Y = y} =
x y x y
! !
X X
= x Pr{X = x} y Pr{Y = y} = E[X]E[Y ].
x y

n general, cnd n variabile aleatoare X1 , X2, . . . , Xn sunt mutual independente

E[X1 X2 . . . Xn ] = E[X1 ]E[X2 ] . . . E[Xn ]. (6.27)

Atunci cnd o variabil aleatoare X ia valori din mulimea numerelor naturale N =


{0, 1, 2, . . .}, exist o formul convenabil pentru media sa

X
X
X
E[X] = i Pr{X = i} = i (Pr{X i} Pr{X i + 1}) = Pr{X i}, (6.28)
i=0 i=0 i=1

deoarece fiecare termen Pr{X i} este adunat de i ori i sczut de i1 ori (exceptnd Pr{X 0}
care este adunat de 0 ori i nu este sczut deloc).

Dispersie i abatere medie ptratic


Dispersia unei variabile aleatoare X cu media E[X] este
h i
2
Var[X] = E (X E[X]) = E X 2 2XE[X] + E 2 [X] =
= E[X 2 ] 2E[XE[X]] + E 2 [X] = E[X 2 ] 2E 2 [X] + E 2 [X] =
= E[X 2 ] E 2 [X]. (6.29)
6.3. Variabile aleatoare discrete 99

Justificarea pentru egalitile E[E 2 [X]] = E 2 [X] i E[XE[X]] = E 2 [X] este aceea c E[X] nu este
o variabil aleatoare, ci pur i simplu un numr real, ceea ce nseamn c se aplic ecuaia (6.25)
(cu a = E[X]). Ecuaia (6.29) poate fi rescris pentru a obine o expresie a mediei ptratului
unei variabile aleatoare:

E[X 2 ] = Var[X] + E 2 [X]. (6.30)

Dispersia unei variabile aleatoare X i dispersia lui aX sunt legate prin

Var[aX] = a2 Var[X].

Cnd X i Y sunt variabile aleatoare independente,

Var[X + Y ] = Var[X] + Var[Y ].

n general, dac n variabile aleatoare X1 , X2 , . . . , Xn sunt dou cte dou independente, atunci
" n # n
X X
V ar Xi = Var[Xi ]. (6.31)
i=1 i=1

Abaterea medie ptratic (deviaia standard ) a variabilei aleatoare X este rdcina


ptrat pozitiv a dispersiei lui X. Abaterea medie ptratic a unei variabile aleatoare X se
noteaz uneori cu X sau cu , cnd variabila aleatoare este subneleas din context. Cu aceast
notaie, dispersia lui X se noteaz cu 2 .

Exerciii
6.3-1 Se arunc dou zaruri obinuite cu 6 fee. Care este media sumei celor dou valori artate
de zaruri? Care este media maximului celor dou valori artate?

6.3-2 Un tablou A[1..n] conine n numere distincte ordonate aleator, fiecare permutare a celor
n numere avnd aceeai probabilitate de apariie. Care este media indicelui elementului maxim
al tabloului? Care este media indicelui elementului minim al tabloului?

6.3-3 La un joc de carnaval se pun trei zaruri ntr-o ceac. Un juctor poate paria 1$ pe orice
numr de la 1 la 6. Ceaca este scuturat, zarurile sunt aruncate, iar plata se face n modul
urmtor. Dac numrul juctorului nu apare pe nici unul din zaruri, el i pierde dolarul. Altfel,
dac numrul su apare pe exact k din cele trei zaruri, k = 1, 2, 3, el i pstreaz dolarul i mai
ctig k dolari. Care este ctigul mediu cnd jocul se joac o singur dat?

6.3-4 ? Fie X i Y variabile aleatoare independente. Artai c f (X) i g(X) sunt independente
pentru orice alegere a funciilor f i g.

6.3-5 ? Fie X o variabil aleatoare nenegativ i presupunem c E[X] este bine definit. De-
monstrai inegalitatea lui Markov :

Pr{X t} E[X]/t (6.32)

pentru orice t > 0.


100 Capitolul 6 Numrare i probabilitate

6.3-6 ? Fie S un spaiu de selecie i X i X 0 variabile aleatoare astfel nct X(s) X 0 (s)
pentru orice s S. Demonstrai c pentru orice constant real t,
Pr{X t} Pr{X 0 t}.

6.3-7 Ce este mai mare: media ptratului unei variabile aleatoare sau ptratul mediei?

6.3-8 Artai c, pentru orice variabil aleatoare X ce ia numai valorile 0 i 1, avem Var[X] =
E[X]E[1 X].

6.3-9 Demonstrai c Var[aX] = a2 Var[X] folosind definiia (6.29) a dispersiei.

6.4. Distribuia geometric i distribuia binomial


Aruncarea unei monede este un exemplu de prob bernoullian, care este definit ca un
experiment cu numai dou rezultate posibile: succes, care apare cu probabilitatea p i eec,
care apare cu probabilitatea q = 1 p. Cnd vorbim de probe bernoulliene n mod colectiv,
nseamn c probele sunt mutual independente i, dac nu se specific altceva, c fiecare are
aceeai probabilitate de succes p. Dou distribuii importante deriv din probele bernoulliene:
distribuia geometric i cea binomial.

Distribuia geometric
Presupunem c avem o secven de probe bernoulliene, fiecare cu probabilitatea de succes
p i probabilitatea de eec q = 1 p. Cte ncercri apar nainte de a obine un succes? Fie
variabila aleatoare X numrul de ncercri necesare pentru a obine un succes. Atunci X ia
valori n domeniul {1, 2, . . .} i pentru k 1
Pr{X = k} = q k1 p, (6.33)
deoarece avem k 1 eecuri naintea unui succes. O distribuie de probabilitate ce satisface
ecuaia (6.33) se numete distribuie geometric. Figura 6.1 ilustreaz o astfel de distribuie.

Presupunnd c p < 1, media distribuiei geometrice poate fi calculat utiliznd identitatea


(3.6):

X
pX k p q
E[X] = kq k1 p = kq = = 1/p. (6.34)
q q (1 q)2
k=1 k=0

Astfel, n medie, este nevoie de 1/p ncercri pentru a obine un succes, rezultat intuitiv.
Dispersia, care se poate calcula n acelai mod, este
Var[X] = q/p2 . (6.35)
De exemplu, s presupunem c aruncm, repetat, dou zaruri pn cnd obinem fie suma apte,
fie suma unsprezece. Din cele 36 de rezultate posibile, 6 ne dau suma apte i 2 suma unsprezece.
Astfel probabilitatea de succes este p = 8/36 = 2/9 i trebuie s aruncm zarurile, n medie, de
1/p = 9/2 = 4.5 ori pentru a obine suma apte sau unsprezece.
6.4. Distribuia geometric i distribuia binomial 101

Figura 6.1 O distribuie geometric cu probabilitatea de succes p = 1/3 i probabilitatea de eec


q = 1 p. Media distribuiei este 1/p = 3.

Distribuia binomial
Cte succese apar n n probe bernouliene, unde un succes apare cu probabilitatea p i un
eec cu probabilitatea q = 1 p? Definim variabila aleatoare X ca fiind numrul de succese n n
probe. Atunci X ia valori n domeniul {0, 1, . . . , n} i pentru k = 0, . . . , n,

n k nk
Pr{X = k} = p q , (6.36)
k

deoarece sunt nk moduri de a alege care k probe din totalul celor n sunt succese i probabilitatea
de apariie a fiecreia dintre ele este pk q nk . O distribuie de probabilitate ce satisface ecuaia
(6.36) se numete distribuie binomial. Pentru comoditate, definim familia distribuiilor bi-
nomiale utiliznd notaia

n k
b(k; n, p) = p (1 p)nk . (6.37)
k
Figura 6.2 ilustreaz o distribuie binomial. Numele de binomial vine de la faptul c (6.37)
este al k-lea termen al dezvoltrii lui (p + q)n . n consecin, deoarece p + q = 1,
n
X
b(k; n, p) = 1, (6.38)
k=0

aa cum cere axioma 2 de probabilitate.


102 Capitolul 6 Numrare i probabilitate

Figura 6.2 Distribuia binomial b(k; 15, 1/3) ce rezult din n = 15 probe bernoulliene, fiecare cu
probabilitatea de succes p = 1/3. Media distribuiei este np = 5.

Putem calcula media unei variabile aleatoare avnd o distribuie binomial din ecuaiile (6.14)
i (6.38). Fie X o variabil aleatoare ce urmeaz distribuia binomial b(k; n, p) i fie q = 1 p.
Din definiia mediei avem
Xn X n X n
n k nk n 1 k1 nk
E[X] = kb(k; n, p) = k p q = np p q =
k k1
k=0 k=1 k=1
X n 1
n1 n1
X
= np pk q (n1)k = np b(k; n 1, p) = np. (6.39)
k
k=0 k=0

Utiliznd liniaritatea mediei, putem obine acelai rezultat cu substanial mai puin algebr. Fie
Xi o variabil aleatoare ce descrie numrul de succese la a i-a prob. Atunci, E[Xi ] = p1+q0 = p
i, din liniaritatea mediei (6.26), numrul mediu de succese din n ncercri este
" n # n n
X X X
E[X] = E Xi = E[Xi ] = p = np.
i=1 i=1 i=1

Aceeai abordare poate fi folosit la calculul dispersiei. Utiliznd ecuaia (6.29), avem Var[Xi ] =
E[Xi2 ] E 2 [Xi ]. Deoarece Xi ia numai valorile 0 i 1, avem E[Xi2 ] = E[Xi ] = p i deci

Var[Xi ] = p p2 = pq. (6.40)

Pentru a calcula dispersia lui X, vom exploata avantajul independenei celor n ncercri; astfel
din ecuaia (6.31)
" n # n n
X X X
Var[X] = Var Xi = Var[Xi ] = pq = npq. (6.41)
i=1 i=1 i=1
6.4. Distribuia geometric i distribuia binomial 103

Conform figurii 6.2, distribuia binomial b(k; n, p) crete pe msur ce k variaz de la 0 la n, pn


cnd atinge media np i apoi scade. Putem demonstra c distribuia se comport ntotdeauna
n acest mod, examinnd raportul termenilor succesivi
n k nk
b(k; n, p) p q n!(k 1)!(n k + 1)!p
= n k k1 nk+1 = =
b(k 1; n, p) k1 p q k!(n k)!n!q
(n k + 1)p (n + 1)p k
= =1+ . (6.42)
kq kq
Acest raport este mai mare dect 1 cnd (n + 1)p k este pozitiv. n consecin, b(k; n, p) >
b(k1; n, p) pentru k < (n+1)p (distribuia crete) i b(k; n, p) < b(k1; n, p) pentru k > (n+1)p
(distribuia descrete). Dac k = (n+1)p este ntreg, atunci b(k; n, p) = b(k1; n, p) i distribuia
are dou maxime: n k = (n + 1)p i n k 1 = (n + 1)p 1 = np q. Altfel, distribuia i atinge
maximul n ntregul k unic, situat n domeniul np q < k < (n + 1)p.
Lema urmtoare ne d o margine superioar a distribuiei binomiale.
Lema 6.1 Fie n 0, 0 < p < 1, q = 1 p i 0 k n. Atunci
np k nq nk
b(k; n, p) .
k nk
Demonstraie. Utiliznd ecuaia (6.10) avem
nk np k nq nk
n k nk n k n k nk
b(k; n, p) = p q p q = .
k k nk k nk

Exerciii
6.4-1 Verificai a doua axiom a probabilitii pentru distribuia geometric.
6.4-2 De cte ori trebuie aruncate, n medie, 6 monede perfecte nainte de a obine 3 steme i
3 bani?
6.4-3 Artai c b(k; n, p) = b(n k; n, q), unde q = 1 p.

6.4-4 Artai c valoarea maxim a distribuiei binomiale b(k; n, p) este aproximativ 1/ 2npq,
unde q = 1 p.
6.4-5 ? Artai c probabilitatea de a nu avea nici un succes din n probe bernoulliene, fiecare
cu probabilitatea p = 1/n, este aproximativ 1/e. Artai c probabilitatea de a avea exact un
succes este, de asemenea, aproximativ 1/e.
6.4-6 ? Profesorul Rosencrantz arunc o moned perfect de n ori i la fel face i profesorul
Guildenstern.
2n n Artai c probabilitatea ca ei s obin acelai numr de steme este egal cu
n /4 . (Indicaie: pentru profesorul Rosencrantz considerm stema succes; pentru profesorul
Guildenstern considerm banul succes). Utilizai raionamentul pentru a verifica identitatea
X n 2
n 2n
= .
k n
k=0
104 Capitolul 6 Numrare i probabilitate

6.4-7 ? Artai c pentru 0 k n,

b(k; n, 1/2) 2nH(k/n)n ,

unde H(x) este funcia entropie binar (6.13).

6.4-8 ? Considerm n probe bernoulliene, unde, pentru i = 1, 2, . . . , n, a i-a prob are proba-
bilitatea de succes pi i fie X variabila aleatoare ce desemneaz numrul total de succese. Fie
p pi pentru orice i = 1, 2, . . . , n. Demonstrai c, pentru 1 k n,
k1
X
Pr{X < k} b(i; n, p).
i=0

6.4-9 Fie X o variabil aleatoare ce reprezint numrul total de succese ntr-o mulime A de n
probe bernoulliene, unde a i-a prob are probabilitatea de succes pi , i fie X 0 variabila aleatoare
ce reprezint numrul total de succese dintr-o mulime A0 de n probe bernoulliene, unde a i-a
prob are o probabilitate de succes p0i pi . Demonstrai c, pentru 0 k n,

Pr{X 0 k} Pr{X k}.

(Indicaie: Artai cum se pot obine probele bernoulliene din A0 printr-un experiment ce implic
probele din A i utilizai rezultatul exerciiului 6.3-6.)

6.5. Cozile distribuiei binomiale


Probabilitatea de a avea cel puin sau cel mult k succese n n probe bernoulliene, fiecare
cu probabilitatea de succes p, este, adesea, de mai mare interes dect probabilitatea de a avea
exact k succese. n aceast seciune vom investiga cozile distribuiei binomiale, adic cele dou
regiuni ale distribuiei b(k; n, p) care sunt ndeprtate de media np.6 Vom demonstra cteva
margini importante (ale sumei tuturor termenilor) dintr-o coad. Vom demonstra, mai nti,
o margine pentru coada dreapt a distribuiei b(k; n, p). Marginile pentru coada stng pot fi
determinate din cele pentru coada dreapt schimbnd ntre ele rolurile succeselor i eecurilor.

Teorema 6.2 Considerm o secven de n probe bernoulliene, unde succesul apare cu proba-
bilitatea p. Fie X o variabil aleatoare ce desemneaz numrul total de succese. Atunci pentru
0 k n, probabilitatea s avem cel puin k succese este
X n
n k
Pr{X k} = b(i; n, p) p .
k
i=k

Demonstraie. Vom utiliza inegalitatea (6.15)



n n nk
.
k+i k i
6 Regiuni de forma {X k} sau {X k} n.t.
6.5. Cozile distribuiei binomiale 105

Avem
n
X nk
X X
nk
n

Pr{X k} = b(i; n, p) = b(k + i; n, p) = pk+i (1 p)n(k+i)
i=0 i=0
k + i
i=k
X nn k
nk nk
n k X nk i

k+i n(k+i)
p (1 p) = p p (1 p)(nk)i
i=0
k i k i=0
i
nk X
n k n k
= p b(i; n k, p) = p ,
k i=0
k
Pnk
cci i=0 b(i; n k, p) = 1, din ecuaia (6.38).
Corolarul urmtor reformuleaz teorema pentru coada stng a distribuiei binomiale. n
general, vom lsa n seama cititorului trecerea de la marginea unei cozi la alta.

Corolarul 6.3 Considerm o secven de n probe bernoulliene, unde succesul apare cu pro-
babilitatea p. Dac X este o variabil aleatoare ce reprezint numrul total de succese, atunci,
pentru 0 k n, probabilitatea s avem cel mult k succese este
k
X
n nk n
Pr{X k} = b(i; n, p) (1 p) = (1 p)nk .
i=0
nk k

Marginea urmtoare se concentreaz asupra cozii stngi a distribuiei binomiale. Cu ct ne


ndeprtm de medie, numrul de succese din coada stng scade exponenial, aa cum ne arat
teorema urmtoare.

Teorema 6.4 Considerm o secven de n probe bernoulliene, n care succesul apare cu proba-
bilitatea p i eecul cu probabilitatea q = 1p. Fie X o variabil aleatoare ce reprezint numrul
de succese. Atunci, pentru 0 < k < np, probabilitatea a mai puin de k succese este
k1
X kq
Pr{X < k} = b(i; n, p) < b(k; n, p).
i=0
np k
Pk1
Demonstraie. Vom majora seria i=0 b(i; n, p) cu o serie geometric utiliznd tehnica din
seciunea 3.2. Pentru i = 1, 2, . . . , k din ecuaia (6.42) avem

b(i 1; n, p) iq i q k q
= < .
b(i; n, p) (n i + 1)p ni p nk p
Dac lum

k q
x= < 1,
nk p
rezult c

b(i 1; n, p) < xb(i; n, p),


106 Capitolul 6 Numrare i probabilitate

pentru 0 < i k. Iternd, obinem

b(i; n, p) < xki b(k; n, p)

pentru 0 i < k i deci


k1
X k1
X
X x kq
b(i; n, p) < xki b(k; n, p) < b(k; n, p) xi = b(k; n, p) = b(k; n, p).
i=0 i=0 i=1
1x np k

Cnd k np/2, avem kq/(np k) 1, ceea ce nseamn c b(k; n, p) majoreaz suma


tuturor termenilor mai mici dect k. De exemplu, s presupunem c aruncm n monede perfecte.
Teorema 6.4 ne spune c, lund p = 1/2 i k = n/4, probabilitatea de a obine mai puin de n/4
steme este mai mic dect probabilitatea de a obine n/4 steme. Mai mult, pentru orice r 4,
probabilitatea de a obine mai puin de n/r steme este mai mic dect probabilitatea de a obine
exact n/r steme. Teorema 6.4 poate fi, de asemenea, util n combinaie cu margini superioare
ale distribuiei binomiale cum ar fi lema 6.1. O margine a cozii drepte se poate determina la fel.

Corolarul 6.5 Considerm o secven de n probe bernoulliene, n care succesul apare cu pro-
babilitatea p. Fie X o variabil aleatoare ce reprezint numrul total de succese. Atunci, pentru
np < k < n, probabilitatea de a avea mai mult de k succese este
n
X (n k)p
Pr{X > k} = b(i; n, p) < b(k; n, p).
k np
i=k+1

Teorema urmtoare consider n probe bernoulliene, fiecare cu o probabilitate pi de succes,


pentru i = 1, 2, . . . , n. Aa cum ne arat corolarul urmtor, putem utiliza teorema pentru a
furniza o margine superioar a cozii drepte a distribuiei binomiale, punnd la fiecare ncercare
p = pi .

Teorema 6.6 Considerm o secven de n probe bernoulliene, unde, la a i-a prob, pentru
i = 1, 2, . . . , n, succesul apare cu probabilitatea pi , iar eecul cu probabilitatea qi = 1 pi . Fie
X o variabil aleatoare ce reprezint numrul total de succese i fie = E [X]. Atunci, pentru
r > ,
e r
Pr{X r} .
r
Demonstraie. Deoarece, pentru orice > 0, funcia ex este strict cresctoare n x, avem

Pr{X r} = Pr{e(X) er },

unde va fi determinat mai trziu. Utiliznd inegalitatea lui Markov (6.32) obinem
h i
Pr{X r} E e(X) er . (6.43)

Partea cea mai consistent a demonstraiei o constituie mrginirea lui E e(X) i substituirea

lui n inegalitea (6.43) cu o valoare potrivit. Mai nti evalum E e(X) . Pentru i =
6.5. Cozile distribuiei binomiale 107

1, 2, . . . , n, fie Xi o variabil aleatoare care are valoarea 1, dac a i-a prob bernoullian este un
succes i 0, dac este un eec. Astfel
n
X
X= Xi
i=1

i
n
X
X = (Xi pi ).
i=1

nlocuind pentru X , obinem


" n #
h i Y n
Y h i
(X) (Xi pi )
E e =E e = E e(Xi pi ) ,
i=1 i=1

care rezult din (6.27) deoarece independena mutual a variabilelor aleatoare Xi implic
independena mutual a variabilelor aleatoare e(Xi pi ) (vezi exerciiul 6.3-4). Din definiia
mediei
h i
E e(Xi pi ) = e(1pi ) pi + e(0pi ) qi = pi eqi + qi epi
pi e + 1 exp(pi e ), (6.44)
x
unde exp(x) reprezint funcia exponenial: exp(x) = e . (Inegalitatea (6.44) rezult din
inegalitile > 0, qi 1, eqi e i epi 1, iar ultima linie rezult din inegalitatea
(2.7)). n consecin,
h i Yn
E e(X) exp(pi e ) = exp(e )
i=1
Pn
cci = i=1 pi . Deci, din inegalitatea (6.43), rezult c
Pr{X r} exp(e r). (6.45)
Alegnd = ln(r/) (vezi exerciiul 6.5-6), obinem
er e r
Pr{X r} exp eln(r/) r ln(r/) = exp(r r ln(r/)) = = .
(r/)r r

Cnd se aplic probelor bernoulliene, n care la fiecare ncercare avem aceeai probabilitate
de succes, teorema 6.6 ne d urmtorul corolar de mrginire a cozii drepte a unei distribuii
binomiale.

Corolarul 6.7 Considerm o secven de n probe bernoulliene, unde, la fiecare prob, succesul
apare cu probabilitatea p, iar eecul cu probabilitatea q = 1 p. Atunci, pentru r > np,
Xn npe r
Pr{X np r} = b(k; n, p) .
r
k=dnp+re

Demonstraie. Pentru o distribuie binomial, (6.39) implic = E [X] = np.


108 Capitolul 6 Numrare i probabilitate

Exerciii
6.5-1 ? Ce este mai puin probabil: s nu obinem nici o stem cnd aruncm o moned perfect
de n ori sau s obinem mai puin de n steme cnd aruncm moneda de 4n ori?

6.5-2 ? Artai c

X
k1
n i k
a < (a + 1)n b(k; n, a/(a + 1)),
i=0
i na k(a + 1)

pentru orice a > 0 i orice k, astfel nct 0 < k < n.

6.5-3 ? Demonstrai c, dac 0 < k < np, unde 0 < p < 1 i q = 1 p, atunci
nk
kq np k
k1
X nq
pi q ni < .
i=0
np k k nk

6.5-4 ? Artai c ipotezele teoremei 6.6 implic


r
(n )e
Pr{ X r} .
r

La fel, artai c ipotezele corolarului 6.7 implic


nqe r
Pr{np X r} .
r

6.5-5 ? Considerm o secven de n probe bernoulliene, unde la a i-a prob, pentru i =


1, 2, . . . , n succesul apare cu probabilitatea pi , iar eecul cu probabilitatea qi = 1 pi . Fie X o
variabil aleatoare ce reprezint numrul total de succese i fie = E [X]. Artai c, pentru
r 0,
2
Pr{X r} er /2n
.
2
(Indicaie: Demonstrai c pi eqi +qi e1pi e /2 . Apoi urmai mersul demonstraiei teoremei
6.6, utiliznd aceast inegalitate n locul inegalitii (6.44).)

6.5-6 ? Artai c, alegnd = ln(r/), se minimizeaz membrul drept al inegalitii (6.45).

6.6. Analiz probabilistic


Aceast seciune utilizeaz trei exemple pentru a ilustra analiza probabilistic. Primul deter-
min probabilitatea ca, ntr-o camer n care sunt k persoane, s existe o anumit pereche care
s-i srbtoreasc ziua de natere n aceeai zi. Al doilea exemplu ilustreaz aruncarea aleatoare
a bilelor n cutii. Al treilea investigheaz secvenele de steme consecutive la aruncarea monedei.
6.6. Analiz probabilistic 109

6.6.1. Paradoxul zilei de natere


Un exemplu bun pentru ilustrarea raionamentului probabilist este clasicul paradox al zilei
de natere. Ci oameni trebuie s fie ntr-o ncpere pentru a avea o bun ans s gsim doi
nscui n aceeai zi a anului? Rspunsul este c trebuie s fie surprinztor de puini. Paradoxul
este acela c, de fapt, trebuie mult mai puini dect numrul de zile dintr-un an, aa cum se va
vedea. Pentru a rspunde la ntrebare, s numerotm oamenii din camer cu ntregii 1, 2, . . . , k,
unde k este numrul de oameni din ncpere. Vom ignora anii biseci i vom presupune c toi
anii au n = 365 de zile. Pentru i = 1, 2, . . . , k, fie bi ziua din an n care cade ziua de natere a
lui i, unde 1 bi n. Presupunem c zilele de natere sunt uniform distribuite n cele n zile ale
anului, aa c Pr{bi = r} = 1/n, pentru i = 1, 2, . . . , k i r = 1, 2, . . . , n.
Probabilitatea ca dou persoane i i j s aib aceeai zi de natere depinde de faptul c
selecia aleatoare este dependent sau independent. Dac zilele de natere sunt independente,
atunci probabilitatea ca ziua de natere a lui i i ziua de natere a lui j s cad amndou n
ziua r este

Pr{bi = r i bj = r} = Pr{bi = r} Pr{bj = r} = 1/n2 .

Astfel, probabilitatea ca ambele s cad n aceeai zi este


n
X Xn
1
Pr{bi = bj } = Pr{bi = r i bj = r} = 2
= 1/n.
r=1 r=1
n

Intutiv, o dat ales bi , probabilitatea ca bj s fie ales acelai, este 1/n. Astfel, probabilitatea ca
i i j s aib aceeai zi de natere este egal cu probabilitatea ca una dintre zilele de natere s
cad ntr-o zi dat. De notat, totui, c aceast coinciden depinde de presupunerea c zilele
de natere sunt independente.
Putem analiza probabilitatea ca cel puin 2 din k oameni s aib aceeai zi de natere, ana-
liznd evenimentul complementar. Probabilitatea ca cel puin dou zile de natere s coincid
este 1 minus probabilitatea ca toate zilele de natere s fie diferite. Evenimentul ca toate cele k
persoane s aib zile de natere distincte este
k1
\
Bk = Ai ,
i=1

unde Ai este evenimentul ca ziua de natere a persoanei (i + 1) s fie diferit de ziua de natere
a persoanei j, pentru orice j i, adic,

Ai = {bi+1 6= bj : j = 1, 2, . . . , i}.

Deoarece putem scrie Bk = Ak1 Bk1 , din ecuaia (6.20) obinem recurena

Pr{Bk } = Pr{Bk1 } Pr{Ak1 |Bk1 }, (6.46)

unde lum Pr{B1 } = 1 drept condiie iniial. Cu alte cuvinte, probabilitatea ca b1 , b2 , . . . , bk


s fie zile de natere distincte este probabilitatea ca b1 , b2 , . . . , bk1 s fie distincte nmulit cu
probabilitatea ca bk 6= bi , pentru i = 1, 2, . . . , k 1, tiind c b1 , b2 , . . . , bk1 sunt distincte.
110 Capitolul 6 Numrare i probabilitate

Dac b1 , b2 , . . . , bk1 sunt distincte, probabilitatea condiionat ca bk 6= bi pentru i =


1, 2, . . . , k 1 este (n k + 1)/n, deoarece printre cele n zile exist n (k 1) care nu sunt luate
n considerare. Iternd recurena (6.46), obinem
Pr{Bk } = Pr{B1 } Pr{A1 |B1 } Pr{A2 |B2 } . . . Pr{Ak1 |Bk1 } =

n1 n2 nk+1
= 1 ... =
n n n

1 2 k1
= 1 1 1 ... 1 .
n n n
Inegalitatea (2.7), 1 + x ex ne d
Pk1
Pr{Bk } e1/n e2/n . . . e(k1)n = e i=1 i/n
= ek(k1)/2n 1/2
cnd k(k 1)/2n ln(1/2). Probabilitatea ca toate cele k p zile de natere s fie distincte este
cel mult 1/2 cnd k(k 1) 2n ln 2, adic pentru k (1 + 1 + (8 ln 2)n)/2, rezultat obinut
rezolvnd inecuaia ptratic. Pentru n = 365, trebuie s avem k 23. Astfel, dac n ncpere
sunt cel puin 23 de oameni, probabilitatea ca cel puin doi s aib aceeai zi de natere este cel
puin 1/2. Pe Marte, unde anul are 669 de zile, este nevoie de 31 de marieni pentru a obine
aceeai probabilitate.

O alt metod de analiz


Putem utiliza liniaritatea mediei (ecuaia (6.26)) pentru o obine o analiz mai simpl, dar
aproximativ, a paradoxului zilei de natere. Pentru fiecare pereche (i, j) dintre cele k persoane
din ncpere, s definim variabilele aleatoare Xij , pentru 1 i < j k, prin

1 dac persoanele i i j au aceeai zi de natere
Xij =
0 n caz contrar.
Probabilitatea ca dou persoane s aib aceeai zi de natere este 1/n i astfel, conform definiiei
mediei (6.23),
E [Xij ] = 1 (1/n) + 0 (1 1/n) = 1/n.
Numrul mediu de perechi de indivizi avnd aceeai zi de natere este, conform ecuaiei (6.24),
suma mediilor individuale ale tuturor perechilor, care este
Xk Xi1
k 1 k(k 1)
E [Xij ] = = .
i=2 j=1
2 n 2n

Cnd k(k 1) 2n, numrul mediu de zile de natere este cel puin 1. Astfel, dac avem
cel puin 2n persoane n ncpere, ne putem atepta ca cel puin dou s aib aceeai zi de
natere. Pentru n = 365, dac k = 28, numrul mediu de persoane cu aceeai zi de natere este
(28 27)/(2 365) 1, 0536. Astfel, dac avem cel puin 28 de persoane, ne ateptm s gsim
cel puin o pereche avnd aceeai zi de natere. Pe Marte, unde un an este de 669 de zile, avem
nevoie de cel puin 38 de marieni.
Prima analiz a determinat numrul de persoane necesar pentru ca probabilitatea existenei
unei coincidene a zilelor de natere s fie mai mare dect 1/2, iar a dou analiz a determinat
6.6. Analiz probabilistic 111

numrul de persoane necesar pentru ca numrul mediu de coincidene de zile de natere s fie
cel puin 1. Dei numrulde oameni determinat n fiecare din cele dou situaii difer, ambele
sunt asimptotic la fel: ( n).

6.6.2. Bile i cutii


Considerm procesul de aruncare aleatoare a unor bile identice n b cutii, numerotate cu
1, 2, . . . , b. Aruncrile sunt independente i, la fiecare aruncare, bila are aceeai probabilitate
de a nimeri n oricare dintre cutii. Probabilitatea ca bila s aterizeze n oricare dintre cutiile
date este 1/b. Astfel, procesul de aruncare a bilelor este o secven de probe bernoulliene cu
o probabilitate de succes de 1/b, unde succes nseamn cderea bilei n cutia dat. Se poate
formula o varietate de ntrebri interesante referitoare la procesul de aruncare a bilelor.
Cte bile cad ntr-o cutie dat? Numrul de bile care cad ntr-o cutie dat urmeaz distribuia
binomial b(k; n, 1/b). Dac se arunc n bile, numrul mediu de bile care cad n cutia dat este
n/b.
Ct de multe bile trebuie aruncate, n medie, pn cnd o cutie dat conine o bil? Numrul
de aruncri, pn cnd cutia dat conine o bil, urmeaz distribuia geometric cu probabilitatea
1/b i astfel numrul mediu de aruncri, pn se obine un succes, este 1/(1/b) = b.
Cte bile trebuie aruncate pn cnd fiecare cutie conine cel puin o bil? S numim lovitur
o aruncare n care o bil cade ntr-o cutie goal. Dorim s tim numrul mediu n de aruncri
necesare pentru a obine b lovituri.
Loviturile se pot utiliza pentru a partiiona cele n aruncri n stadii. Al i-lea stadiu const
din aruncrile de dup a (i 1)-a lovitur pn la a i-a lovitur. Primul stadiu const din prima
aruncare, deoarece ni se garanteaz c avem o lovitur atunci cnd toate cutiile sunt goale.
Pentru fiecare aruncare din timpul celui de-al i-lea stadiu, exist i 1 cutii ce conin bile i
b i + 1 cutii goale. Astfel, pentru toate aruncrile din stadiul i, probabilitatea de a obine o
lovitur este (b i + 1)/b.
Fie ni numrul de aruncri Pb la al i-lea stadiu. Astfel, numrul de aruncri necesare pentru a
obine b lovituri este n = i=1 ni . Fiecare variabil aleatoare ni are o distribuie geometric cu
probabilitatea de succes (b i + 1)/b i de aceea
b
E [ni ] = .
bi+1
Din liniaritatea mediei, obinem
" b # b b b
X X X b X 1
E [n] = E ni = E [ni ] = =b = b(ln b + O(1)).
i=1 i=1 i=1
bi+1 i=1
i

Ultima inegalitate rezult din marginea (3.5) referitoare la seria armonic. Deci sunt necesare
aproximativ b ln b aruncri nainte de a ne putea atepta ca fiecare cutie s conin o bil.

6.6.3. Linii (secvene)


S presupunem c aruncm o moned perfect de n ori. Care este cea mai lung linie
(secven) de steme consecutive pe care ne ateptm s-o obinem? Rspunsul este (lg n), aa
cum ne arat analiza urmtoare.
112 Capitolul 6 Numrare i probabilitate

Vom demonstra, nti, c lungimea celei mai lungi secvene de steme este O(lg n). Fie Aik
evenimentul ca o secven de steme de lungime cel puin k s nceap de la a i-a aruncare sau,
mai precis, evenimentul ca cele k aruncri consecutive, i, i + 1, . . . , i + k 1 s ne dea numai
steme, unde 1 k n i 1 i n k + 1. Pentru un eveniment dat Aik , probabilitatea ca
toate cele k aruncri s aib ca rezultat stema, are o distribuie geometric cu p = q = 1/2:

Pr{Aik } = 1/2k . (6.47)

Pentru k = 2 dlg ne,



Pr Ai,2dlg ne = 1/22dlg ne 1/22 lg n = 1/n2 ,

i, astfel, probabilitatea ca o secven de steme de lungime cel puin d2 lg ne s nceap din


poziia i este chiar mic, considernd c sunt cel mult n poziii (de fapt n 2dlg ne + 1) n care
secvena ar putea ncepe. Probabilitatea ca o secven de steme de lungime cel puin d2 lg ne s
nceap oriunde este deci

n2dlg
[ne+1 X n
1
Pr Ai,2dlg ne 1/n2 = ,
n
i=1 i=1

deoarece, conform inegalitii lui Boole (6.22), probabilitatea unei reuniuni de evenimente este
cel mult suma probabilit ilor evenimentelor individuale. (De notat c inegalitatea lui Boole are
loc i pentru evenimente care nu sunt independente.)
Probabilitatea ca orice secven s aib lungimea cel puin 2dlg ne este cel mult 1/n; deci
probabilitatea ca cea mai lung secven s aib lungimea mai mic dect 2dlg ne este cel puin
1 1/n. Deoarece fiecare secven are lungimea cel mult n, lungimea medie a celei mai lungi
secvene este mrginit superior de

(d2 lg ne)(1 1/n) + n(1/n) = O(lg n).

ansa ca o secven de steme s depeasc rdlg ne se diminueaz rapid o dat cu r. Pentru


r 1, probabilitatea ca o secven de rdlg ne s nceap n poziia i este

Pr{Ai,rdlg ne } = 1/2rdlg ne 1/nr .

Astfel, probabilitatea ca cea mai lung secven s aib lungimea cel puin rdlg ne este cel mult
n/nr = 1/nr1 , sau echivalent, probabilitatea ca cea mai lung secven s aib lungimea mai
mic dect rdlg ne este cel puin 1 1/nr1 .
De exemplu, pentru n = 1000 de aruncri de moned, probabilitatea de a avea o secven de
cel puin 2dlg ne = 20 de steme este de cel mult 1/n = 1/1000. ansa de a avea o secven mai
lung de 3dlg ne = 30 de steme este de cel mult 1/n2 = 1/1000000.
Vom demonstra acum o margine inferioar complementar: lungimea celei mai lungi secvene
de steme n n aruncri este (lg n). Pentru a demonstra aceast margine vom cuta o secven
de lungime blg nc/2. Din ecuaia (6.47) avem

Pr{Ai,blg nc/2 } = 1/2blg nc/2 1/ n.

Probabilitatea
ca o secven de lungime cel puin blg nc/2 s nu nceap n poziia i este deci cel
mult 1 1/ n. Putem partiiona cele n aruncri ale monedei n cel puin b2n/blg ncc grupuri
Probleme 113

de blg nc/2 aruncri consecutive de monede. Deoarece aceste grupuri sunt formate din aruncri
mutual exclusive i independente, probabilitatea ca nici unul dintre aceste grupuri s nu fie o
secven de lungime blg nc/2 este

(1 1/ n)b2n/blg ncc (1 1/ n)2n/ lg n1 e(2n/ lg n1)/ n = O(e lg n ) = O(1/n).

Pentru a justifica aceasta, am utilizat inegalitatea (2.7), 1 + x ex . Astfel, probabilitatea ca


cea mai lung linie s depeasc blg nc/2 este cel puin 1 O(1/n). Deoarece cea mai lung
secven are lungimea cel puin 0, lungimea medie a celei mai lungi linii (secvene) este de cel
puin

(blg nc/2)(1 O(1/n)) + 0 (1/n) = (lg n).

Exerciii
6.6-1 Presupunem c mai multe bile sunt aruncate n b cutii. Fiecare aruncare este independent
i fiecare bil are aceeai probabilitate de a ajunge n oricare dintre cutii. Care este numrul mediu
de bile aruncate, nainte ca cel puin una din cutii s conin dou bile?

6.6-2 ? Pentru analiza paradoxului zilei de natere, este important ca zilele de natere s fie
independente n totalitate (mutual independente) sau este suficient s fie independente dou cte
dou? Justificai rspunsul.

6.6-3 ? Ci oameni trebuie invitai la o petrecere pentru a face verosimil existena a trei
dintre ei cu aceeai zi de natere?

6.6-4 ? Care este probabilitatea ca un k-ir peste o mulime de lungime n s fie o k-permutare?
Ce legtur este ntre aceast chestiune i paradoxul zilei de natere?

6.6-5 ? Presupunem c n bile sunt aruncate n n cutii, fiecare aruncare este independent i
fiecare bil are aceeai probabilitate de a nimeri n oricare dintre cutii. Care este numrul mediu
de cutii goale? Care este numrul mediu de cutii cu exact o bil?

6.6-6 ? mbuntii marginea inferioar a lungimii unei secvene artnd c, pentru n aruncri
ale unei monede perfecte, probabilitatea ca s nu apar nici o linie de mai mult de lg n 2 lg lg n
steme consecutive este mai mic dect 1/n.

Probleme
6-1 Bile i cutii
n aceast problem investigm efectul diverselor ipoteze asupra numrului de moduri de a plasa
n bile n b cutii distincte.

a. S presupunem c cele n bile sunt distincte i ordinea lor ntr-o cutie nu conteaz.
Argumentai c numrul de moduri n care se pot aeza bilele n cutii este bn .
114 Capitolul 6 Numrare i probabilitate

b. S presupunem c bilele sunt distincte i c bilele din fiecare cutie sunt ordonate.
Demonstrai c numrul de moduri n care se pot aeza bilele n cutii este (b+n1)!/(b1)!.
(Indicaie: Considerai numrul de moduri de aranjare a n bile distincte i b 1 beioare
nedistinctibile ntr-un rnd.)
c. Presupunem c bilele sunt identice i c ordinea lor n cutie nu conteaz. Artai c
numrul de moduri n care se pot aeza bilele n cutii este b+n1
n . (Indicaie: cte dintre
aranjamentele din partea (b) se repet dac bilele devin identice?)
d. Presupunem c bilele sunt identice i c nici o cutie nuconine
mai mult de o bil. Artai
c numrul de moduri n care se pot aeza bilele este nb .
e. Presupunem c bilele sunt identice i c nici o cutie
nu poate rmne goal. Artai c
numrul de moduri n care se pot aeza bilele este n1
b1 .

6-2 Analiza programului de determinare a maximului


Programul urmtor determin valoarea maxim dintr-un tablou neordonat A[1..n].

1: max
2: pentru i 1, n execut
3: . Compar A[i] cu max
4: dac A[i] > max atunci
5: max A[i]
Dorim s determinm numrul mediu de execuii ale atribuirii din linia 5. Presupunem c
numerele din A sunt o permutare aleatoare a n numere distincte.
a. Dac un numr x este ales aleator dintr-o mulime de i numere distincte, care este proba-
bilitatea ca x s fie cel mai mare din mulime?
b. Care este relaia dintre A[i] i A[j] cnd se execut linia 5 a programului, pentru 1 j i?
c. Pentru orice i din domeniul 1 i n, care este probabilitatea ca linia 5 s fie executat?
d. Fie s1 , s2 , . . . , sn n variabile aleatoare, unde si reprezint numrul de execuii (0 sau 1) ale
liniei 5 n timpul celei de-a i-a iteraii a ciclului pentru. Ce este E[si ]?
e. Fie s = s1 + s2 + + sn numrul total de execuii ale liniei 5 n timpul unei execuii a
programului. Artai c E[s] = (lg n).

6-3 Problema angajrii


D-na profesoar Dixon vrea s angajeze un nou asistent cercettor. Ea a aranjat interviuri cu n
solicitani i vrea s-i bazeze decizia doar pe calificarea lor. Din nefericire, regulile universitii
cer ca dup fiecare interviu candidatul s fie respins sau s i se ofere postul solicitat. Profesoara
Dixon a decis s adopte strategia de a selecta un ntreg pozitiv k < n, s intervieveze i s
resping primii k solicitani i apoi s-l angajeze pe solicitantul care este mai pregtit dect toi
solicitanii precedeni. Dac cel mai bun este ntre primii k intervievai, va fi angajat al n-lea
solicitant. Artai c d-na profesoar Dixon i maximizeaz ansa de a angaja cel mai bine
pregtit solicitant, alegnd k aproximativ egal cu n/e i c ansa de a-l angaja pe cel mai bine
pregtit este atunci aproximativ 1/e.
Note bibliografice 115

6-4 Numrare probabilistic


Cu un contor de t bii putem numra n mod obinuit pn la 2t 1. Cu numrarea
probabilistic a lui R. Morris putem numra pn la valori mult mai mari, cu preul unei
pierderi a preciziei. Vom lua o valoare de contor i care va reprezenta numrul de ni , pentru
i = 0, 1, . . . , 2t 1, unde ni formeaz o secven cresctoare de valori nenegative. Vom presupune
c valoarea iniial a contorului este 0, reprezentnd numrul de valori n0 = 0. Operaia
Incrementeaz lucreaz pe un contor ce conine valoarea i n mod probabilist. Dac i = 2t 1,
se raporteaz o eroare de tip depire superioar. Altfel, contorul este incrementat cu 1 cu proba-
bilitatea 1/(ni+1 ni ) i rmne neschimbat cu probabilitatea 1 1/(ni+1 ni ). Dac selectm
ni = i, pentru orice i 0, atunci contorul este unul obinuit. O situaie mai interesant apare
dac selectm, de exemplu, ni = 2i1 , pentru i > 0, sau ni = Fi (al i-lea numr Fibonacci vezi
seciunea 2.2). Pentru aceast problem s presupunem c n2t 1 este suficient de mare, astfel
ca probabilitatea unei depiri superioare s fie neglijabil.

a. Artai c valoarea medie reprezentat de contor, dup ce au fost efectuate n operaii


Incrementeaz, este exact n.
b. Analiza dispersiei numrului reprezentat de contor depinde de secvena de numere ni .
S considerm un caz simplu: ni = 100i, pentru orice i 0. Estimai dispersia valorii
reprezentate de registru dup ce au fost efectuate n operaii Incrementeaz.

Note bibliografice
Primele metode generale de rezolvare a problemelor de probabiliti au fost discutate n
celebra coresponden dintre B. Pascal i P. de Fermat, care a nceput n 1654 i ntr-o carte a
lui C. Huygens din 1657. Teoria riguroas a probabilitilor a nceput cu lucrarea lui J. Bernoulli
din 1713 i cu cea a lui A. de Moivre din 1730. Dezvoltri ulterioare ale teoriei au fost date de
P. S. de Laplace, S.-D. Poisson i C. F. Gauss.
Sumele de variabile aleatoare au fost studiate pentru prima dat de P. L. Chebyshev (Cebev)
i de A. A. Markov. Teoria probabilitilor a fost axiomatizat de A. N. Kolmogorov n 1933.
Marginile pentru cozile distribuiilor au fost date de Chernoff [40] i Hoeffding [99]. Lucrarea de
baz referitoare la structurile aleatoare combinatorice a fost dat de P. Erds.
Knuth [121] i Liu [140] sunt referine bune pentru combinatoric elementar i numrare.
Cri standard ca Billingsley [28], Chung [41], Drake [57], Feller [66] i Rozanov [171] dau o
introducere comprehensiv n teoria probabilitilor. Bollobs [30], Hofri [100] i Spencer [179]
conin o mare varietate de tehnici probabilistice avansate.
II Ordonare i statistici de ordine
Introducere
Aceast parte prezint mai muli algoritmi care rezolv urmatoarea problem de ordonare:
Intrare: Un ir de n numere ha1 , a2 , ..., an i.
Ieire: O permutare (reordonare) ha01 , a02 , ..., a0n i a irului dat astfel nct a01 a0n .
irul de intrare este, de obicei, un tablou cu n elemente, dei el poate fi reprezentat i n alt mod,
de exemplu sub forma unei liste nlnuite.

Structura datelor
n practic, numerele care trebuie ordonate sunt rareori valori izolate. De obicei, fiecare
numr face parte dintr-o colecie de date numit articol. Fiecare articol conine o cheie, care
este valoarea ce trebuie ordonat, iar restul articolului conine date adiionale, care sunt, de
obicei, mutate mpreun cu cheia. n practic, atunci cnd un algoritm de ordonare interschimb
cheile, el trebuie s interschimbe i datele adiionale. Dac fiecare articol include o cantitate
mare de date adiionale, de multe ori interschimbm un tablou de pointeri la articole, n loc s
interschimbm articolele nsei, cu scopul de a minimiza cantitatea de date care este manevrat.

Dintr-un anumit punct de vedere, tocmai aceste detalii de implementare disting un algoritm
de programul propriu-zis. Faptul c sortm numere individuale sau articole mari, ce conin
numere, este irelevant pentru metoda prin care o procedur de ordonare determin ordinea
elementelor. Astfel, atunci cnd ne concentrm asupra problemei sortrii, presupunem, de obicei,
c intrarea const numai din numere. Implementarea unui algoritm care sorteaz numere este
direct din punct de vedere conceptual, dei, ntr-o situaie practic dat, pot exista i alte
subtiliti care fac ca implementarea propriu-zis a algoritmului s fie o sarcin dificil.

Algoritmi de sortare
n capitolul 1 am prezentat doi algoritmi care ordoneaz n numere naturale. Sortarea prin
inserie necesit, n cazul cel mai defavorabil, un timp de ordinul (n2 ). Totui, datorit faptului
c buclele sale interioare sunt mici, el este un algoritm rapid de sortare pe loc pentru dimensiuni
mici ale datelor de intrare. (Reamintii-v faptul c un algoritm de sortare sorteaz pe loc dac
doar un numr constant de elemente ale tabloului de intrare sunt stocate n afara tabloului la un
moment dat.) Sortarea prin interclasare are un timp de execuie asimptotic mai bun, (n lg n),
dar procedura Merge nu sorteaz n loc.
n aceast parte, vom introduce doi algoritmi noi de sortare pentru numere reale arbitrare.
Heapsort, prezentat n capitolul 7, sorteaz pe loc n numere arbitrare ntr-un timp O(n lg n).
Acest algoritm folosete o structur de date important, numit heap, pentru a implementa o
coad de prioritate.
Sortarea rapid, prezentat n capitolul 8, sorteaz i ea pe loc n numere, dar timpul su de
execuie, pentru cazul cel mai defavorabil, este (n2 ). Timpul mediu de execuie este (n lg n)
i, de obicei, mai bun dect este, n practic, Heapsort. La fel ca sortarea prin inserie, quicksort
are un cod foarte compact, i, deci, factorul constantei ascunse din timpul su de execuie este
mic. Sortarea rapid este un algoritm pentru sortarea tablourilor de dimensiuni foarte mari.
118

Sortarea prin inserie, sortarea prin interclasare, heapsort i sortarea rapid sunt toi algoritmi
de sortare prin comparare: ei determin ordinea elementelor unui tablou de intrare comparndu-i
elementele. Capitolul 9 ncepe prin introducerea modelului arborelui de decizie pentru studiul
limitrilor de performan ale sortrilor prin comparare. Folosind acest model, vom demonstra
o limit inferioar de (n lg n) pentru timpul de execuie al celui mai defavorabil caz al oricrei
sortri prin comparare a n elemente, demonstrnd astfel c heapsort i sortarea prin interclasare
sunt sortri prin comparare, optime din punct de vedere asimptotic.
n capitolul 9, se arat, apoi, c putem nvinge aceast limit inferioar de (n lg n)
dac putem aduna informaii despre ordinea elementelor prin alte mijloace dect compararea
elementelor. De exemplu, algoritmul de sortare prin numrare presupune c numerele de
intrare fac parte din mulimea {1, 2, ..., k}. Folosind indexarea tablourilor ca instrument pentru
determinarea ordinii relative, sortarea prin numrare poate sorta n numere ntr-un timp de
ordinul O(k + n). Astfel, atunci cnd k = O(n), sortarea prin numrare se execut ntr-un timp
ce depinde, liniar, de numrul elementelor din tabloul de intrare. Un algoritm nrudit, radix
sort, poate fi folosit pentru a extinde domeniul ordonrii prin numrare. Dac avem de ordonat
n numere ntregi, fiecare numr avnd d cifre, cu fiecare cifr aparinnd mulimii {1, 2, ..., k},
sortarea pe baza cifrelor poate ordona numerele ntr-un timp de ordinul O(d(n + k)). Dac d
este constant i k este O(n), sortarea pe baza cifrelor se execut ntr-un timp liniar. Un al treilea
algoritm, sortarea pe grupe, necesit informaii despre distribuia probabilistic a numerelor
din tabloul de intrare. Algoritmul poate sorta n numere reale, distribuite uniform n intervalul
semideschis [0, 1), ntr-un timp mediu de ordinul O(n).

Statistici de ordine
Statistica de ordinul i a unei mulimi de n numere este al i-lea cel mai mic numr din
mulime. Desigur, o persoan poate determina statistica de ordinul i, sortnd intrarea i selectnd
elementul cu indicele i al ieirii. Fr nici o presupunere despre distribuia elementelor, aceast
metod ruleaz ntr-un timp de ordinul (n lg n), dup cum arat i limita inferioar determinat
n capitolul 9.
n capitolul 10, vom arta c putem determina al i-lea cel mai mic element n timpul O(n),
chiar i atunci cnd elementele sunt numere reale arbitrare. Vom prezenta un algoritm avnd
un pseudocod compact care se execut n timpul O(n2 ) n cazul cel mai defavorabil, dar ntr-un
timp liniar n cazul general. Vom da, de asemenea, i un algoritm mai complicat, care se execut
ntr-un timp O(n) n cazul cel mai defavorabil.

Fundamente
Dei cele mai multe lucruri prezentate n aceast parte nu se bazeaz pe elemente matematice
dificile, anumite seciuni cer o abordare sofisticat din punct de vedere matematic. n special,
analizele timpilor medii de execuie ai algoritmilor de sortare rapida, sortare pe grupe, precum i
ai algoritmului bazat pe statistici de ordine folosesc elemente de probabilistic, elemente ce sunt
prezentate n capitolul 6. Analiza timpului de execuie al statisticii de ordine pentru cazul cel
mai defavorabil necesit elemente matematice puin mai sofisticate dect celelalte analize pentru
timpii de execuie n cazurile cele mai defavorabile din aceast parte.
7 Heapsort

n acest capitol vom prezenta un nou algoritm de sortare. Asemntor sortrii prin inter-
clasare, dar diferit de sortarea prin inserare, timpul de execuie al agoritmului heapsort este
O(n lg n). Asemntor sortrii prin inserare i diferit de sortarea prin interclasare, prin heapsort
se ordoneaz elementele n spaiul alocat vectorului: la un moment dat doar un numr constant
de elemente ale vectorului sunt pstrate n afara spaiului alocat vectorului de intrare. Astfel,
algoritmul heapsort combin calitile celor doi algoritmi de sortare prezentai deja.
Heapsort introduce o tehnic nou de proiectare a algoritmilor bazat pe utilizarea unei
structuri de date, numit de regul heap1 . Structura de date heap este util nu doar pentru
algoritmul heapsort, ea poate fi la fel de util i n tratarea eficient a unei cozi de prioritate.
Cu structura de date heap ne vom mai ntlni n algoritmii din capitolele urmtoare.
Amintim c termenul heap a fost introdus i utilizat iniial n contextul algoritmului heapsort,
dar acesta se folosete i n legtur cu alocarea dinamic, respectiv n tratarea memoriei bazate
pe colectarea reziduurilor (garbage collected storage), de exemplu n limbajele de tip Lisp.
Structura de date heap nu se refer la heap-ul menionat n alocarea dinamic, i ori de cte ori,
n aceast carte vom vorbi despre heap, vom nelege structura definit n acest capitol.

7.1. Heap-uri
Structura de date heap (binar) este un vector care poate fi vizualizat sub forma unui
arbore binar aproape complet (vezi seciunea 5.5.3), conform figurii 7.1. Fiecare nod al arborelui
corespunde unui element al vectorului care conine valorile ataate nodurilor. Arborele este plin,
exceptnd eventual nivelul inferior, care este plin de la stnga la dreapta doar pn la un anumit
loc. Un vector A care reprezint un heap are dou atribute: lungime[A], reprezint numrul
elementelor din vector i dimensiune-heap[A] reprezint numrul elementelor heap-ului memorat
n vectorul A. Astfel, chiar dac A[1..lungime[A]] conine n fiecare element al su date valide,
este posibil ca elementele urmtoare elementului A[dimensiune-heap[A]], unde dimensiune-
heap[A] lungime[A], s nu aparin heap-ului. Rdcina arborelui este A[1]. Dat fiind un
indice i, corespunztor unui nod, se pot determina uor indicii printelui acestuia Printe(i),
al fiului Stnga(i) i al fiului Dreapta(i).
Printe(i)
returneaz bi/2c

Stnga(i)
returneaz 2i

Dreapta(i)
returneaz 2i + 1
1 unii autori romni, folosesc termenul ansamblu.
120 Capitolul 7 Heapsort

Figura 7.1 Un heap reprezentat sub forma unui arbore binar (a) i sub forma unui vector (b). Numerele
nscrise n cercurile reprezentnd nodurile arborelui sunt valorile ataate nodurilor, iar cele scrise lng
cercuri sunt indicii elementelor corespunztoare din vector.

n cele mai multe cazuri, procedura Stnga poate calcula valoarea 2i cu o singur instruc-
iune, translatnd reprezentarea binar a lui i la stnga cu o poziie binar. Similar, procedura
Dreapta poate determina rapid valoarea 2i + 1, translatnd reprezentarea binar a lui i la
stnga cu o poziie binar, iar bitul nou intrat pe poziia binar cea mai nesemnificativ va fi
1. n procedura Printe valoarea bi/2c se va calcula prin translatarea cu o poziie binar la
dreapta a reprezentrii binare a lui i. ntr-o implementare eficient a algoritmului heapsort, aceste
proceduri sunt adeseori codificate sub forma unor macro-uri sau a unor proceduri in-line.
Pentru orice nod i, diferit de rdcin, este adevrat urmtoarea proprietate de heap:

A[Printe(i)] A[i], (7.1)

adic valoarea ataat nodului este mai mic sau egal cu valoarea asociat printelui su. Astfel
cel mai mare element din heap este pstrat n rdcin, iar valorile nodurilor oricrui subarbore
al unui nod sunt mai mici sau egale cu valoarea nodului respectiv.
Definim nlimea unui nod al arborelui ca fiind numrul muchiilor aparinnd celui mai
lung drum care leag nodul respectiv cu o frunz, iar nlimea arborelui ca fiind nlimea
rdcinii. Deoarece un heap avnd n elemente corespunde unui arbore binar complet, nlimea
acestuia este (lg n) (vezi exerciiul 7.1-2). Vom vedea c timpul de execuie al operaiilor de
baz, care se efectueaz pe un heap, este proporional cu nlimea arborelui i este O(lg n). n
cele ce urmeaz, vom prezenta cinci proceduri i modul lor de utilizare n algoritmul de sortare,
respectiv ntr-o structur de tip coad de prioritate.

Procedura Reconstituie-Heap are timpul de execuie O(lg n) i este de prim importan


n ntreinerea proprietii de heap (7.1).

Procedura Construiete-Heap are un timp de execuie liniar i genereaz un heap dintr-


un vector neordonat, furnizat la intrare.

Procedura Heapsort se execut n timpul O(n lg n) i ordoneaz un vector n spaiul


alocat acestuia.

Procedurile Extrage-Max i Insereaz se execut n timpul O(lg n), iar cu ajutorul lor
se poate utiliza un heap n realizarea unei cozi de prioritate.
7.2. Reconstituirea proprietii de heap 121

Exerciii
7.1-1 Care este cel mai mic, respectiv cel mai mare numr de elemente dintr-un heap avnd
nlimea h?

7.1-2 Artai c un heap avnd n elemente are nlimea blg nc.

7.1-3 Artai c n orice subarbore al unui heap, rdcina subarborelui conine cea mai mare
valoare care apare n acel subarbore.

7.1-4 Unde se poate afla cel mai mic element al unui heap, presupunnd c toate elementele
sunt distincte?

7.1-5 Este vectorul n care elementele se succed n ordine descresctoare un heap?

7.1-6 Este secvena h23, 17, 14, 6, 13, 10, 1, 5, 7, 12i un heap?

7.2. Reconstituirea proprietii de heap


Procedura Reconstituie-Heap este un subprogram important n prelucrarea heap-urilor.
Datele de intrare ale acesteia sunt un vector A i un indice i din vector. Atunci cnd se apeleaz
Reconstituie-Heap, se presupune c subarborii, avnd ca rdcini nodurile Stnga(i)
respectiv Dreapta(i), sunt heap-uri. Dar, cum elementul A[i] poate fi mai mic dect descendenii
si, acesta nu respect proprietatea de heap (7.1). Sarcina procedurii Reconstituie-Heap este
de a scufunda n heap valoarea A[i], astfel nct subarborele care are n rdcin valoarea
elementului de indice i, s devin un heap.
Reconstituie-Heap(A, i)
1: l Stnga(i)
2: r Dreapta(i)
3: dac l dimesiune-heap[A] i A[l] > A[i] atunci
4: maxim l
5: altfel
6: maxim i
7: dac r dimesiune-heap[A] i A[r] > A[maxim] atunci
8: maxim r
9: dac maxim 6= i atunci
10: schimb A[i] A[maxim]
11: Reconstituie-Heap(A, maxim)

Figura 7.2 ilustreaz efectul procedurii Reconstituie-Heap. La fiecare pas se determin cel
mai mare element dintre A[i], A[Stnga(i)] i A[Dreapta(i)], iar indicele su se pstreaz n
variabila maxim. Dac A[i] este cel mai mare, atunci subarborele avnd ca rdcin nodul i este
un heap i procedura se termin. n caz contrar, cel mai mare element este unul dintre cei doi
descendeni i A[i] este interschimbat cu A[maxim]. Astfel, nodul i i descendenii si satisfac
proprietatea de heap. Nodul maxim are acum valoarea iniial a lui A[i], deci este posibil ca
122 Capitolul 7 Heapsort

Figura 7.2 Efectul procedurii Reconstituie-Heap(A, 2), unde dimesiune-heap[A] = 10. (a)
Configuraia iniial a heap-ului, unde A[2] (pentru nodul i = 2), nu respect proprietatea de heap
deoarece nu este mai mare dect descendenii si. Proprietatea de heap este restabilit pentru nodul 2
n (b) prin interschimbarea lui A[2] cu A[4], ceea ce anuleaz proprietatea de heap pentru nodul 4. Apelul
recursiv al procedurii Reconstituie-Heap(A, 4) poziioneaz valoarea lui i pe 4. Dup interschimbarea
lui A[4] cu A[9], aa cum se vede n (c), nodul 4 ajunge la locul su i apelul recursiv Reconstituie-
Heap(A, 9) nu mai gsete elemente care nu ndeplinesc proprietatea de heap.

subarborele de rdcin maxim s nu ndeplineasc proprietatea de heap. Rezult c procedura


Reconstituie-Heap trebuie apelat recursiv din nou pentru acest subarbore.
Timpul de execuie al procedurii Reconstituie-Heap, corespunztor unui arbore de rd-
cin i i dimensiune n, este (1), timp n care se pot analiza relaiile dintre A[i], A[Stnga(i)] i
A[Dreapta(i)] la care trebuie adugat timpul n care Reconstituie-Heap se execut pentru
subarborele avnd ca rdcin unul dintre descendenii lui i. Dimensiunea acestor subarbori este
de cel mult 2n/3 cazul cel mai defavorabil fiind acela n care nivelul inferior al arborelui este
plin exact pe jumtate astfel, timpul de execuie al procedurii Reconstituie-Heap poate fi
descris prin urmtoarea inegalitate recursiv:

T (n) T (2n/3) + (1).

Soluia acestei recurene se obine pe baza celui de-al doilea caz al teoremei master (teorema
4.1): T (n) = O(lg n). Timpul de execuie al procedurii Reconstituie-Heap pentru un nod de
nlime h poate fi exprimat alternativ ca fiind egal cu O(h).
7.3. Construirea unui heap 123

Exerciii
7.2-1 Utiliznd ca model figura 7.2, ilustrai modul de funcionare al procedurii Reconstituie-
Heap(A, 3) pentru vectorul A = h27, 17, 3, 16, 13, 10, 1, 5, 7, 12, 4, 8, 9, 0i.

7.2-2 Care este efectul apelului procedurii Reconstituie-Heap(A, i), dac elementul A[i] este
mai mare dect descendenii si?

7.2-3 Care este efectul procedurii Reconstituie-Heap(A, i) pentru i > dimesiune-heap[A]/2?

7.2-4 Procedura Reconstituie-Heap poate fi implementat eficient din punct de vedere al


timpului constant de execuie, dar se poate ntmpla ca anumite compilatoare s genereze cod
ineficient pentru apelul recursiv din linia a 11-a. Elaborai o variant a procedurii Reconsti-
tuie-Heap, n care recursivitatea este nlocuit cu iterativitate.

7.2-5 Artai c timpul de execuie a procedurii Reconstituie-Heap, n cazul unui heap de


dimensiune n, este, n cel mai defavorabil caz, (lg n). (Indicaie: n cazul unui heap format din
n elemente, determinai valorile ataate nodurilor astfel nct procedura Reconstituie-Heap
s fie apelat recursiv pentru toate nodurile aparinnd drumurilor care pornesc de la rdcin
la frunze.)

7.3. Construirea unui heap


Procedura Reconstituie-Heap poate fi utilizat de jos n sus pentru transformarea
vectorului A[1..n] n heap, unde n = lungime[A]. Deoarece toate elementele subirului A[(bn/2c+
1)..n] sunt frunze, acestea pot fi considerate ca fiind heap-uri formate din cte un element. Astfel,
procedura Construiete-Heap trebuie s traverseze doar restul elementelor i s execute
procedura Reconstituie-Heap pentru fiecare nod ntlnit. Ordinea de prelucrare a nodurilor
asigur ca subarborii, avnd ca rdcin descendeni ai nodului i s formeze heap-uri nainte ca
Reconstituie-Heap s fie executat pentru aceste noduri.
Construiete-Heap(A)
1: dimesiune-heap[A] lungime[A]
2: pentru i blungime[A]/2c,1 execut
3: Reconstituie-Heap(A, i)

Figura 7.3 ilustreaz modul de funcionare al procedurii Construiete-Heap.


Timpul de execuie al procedurii Construiete-Heap poate fi calculat simplu, determinnd
limita superioar a acestuia: fiecare apel al procedurii Reconstituie-Heap necesit un timp
O(lg n) i, deoarece pot fi O(n) asemenea apeluri, rezult c timpul de execuie poate fi cel mult
O(n lg n). Aceast estimare este corect, dar nu este suficient de tare asimptotic.
Vom obine o limit mai tare observnd c timpul de execuie a procedurii Reconstituie-
Heap depinde de nlimea nodului n arbore, aceasta fiind mic pentru majoritatea nodurilor.
Estimarea noastr mai riguroas se bazeaz pe faptul c un heap avnd n elemente are nlimea
lg n (vezi exerciiul 7.1-2) i c pentru orice nlime h, n heap exist cel mult bn/2h+1 c noduri
de nlime h (vezi exerciiul 7.3-3).
124 Capitolul 7 Heapsort

Figura 7.3 Modul de execuie a procedurii Construiete-Heap. n figur se vizualizeaz structurile


de date n starea lor anterioar apelului procedurii Reconstituie-Heap (linia 3 din procedura
Construiete-Heap). (a) Se consider un vector A avnd 10 elemente i arborele binar corespunztor.
Dup cum se vede n figur, variabila de control i a ciclului, n momentul apelului Reconstituie-
Heap(A, i), indic nodul 5. (b) reprezint rezultatul; variabila de control i a ciclului acum indic nodul
4. (c) - (e) vizualizeaz iteraiile succesive ale ciclului pentru din Construiete-Heap. Se observ
c, atunci cnd se apeleaz procedura Reconstituie-Heap pentru un nod dat, subarborii acestui nod
sunt deja heap-uri. (f ) reprezint heap-ul final al procedurii Construiete-Heap.
7.4. Algoritmul heapsort 125

Timpul de execuie a procedurii Reconstituie-Heap pentru un nod de nlime h fiind


O(h), obinem pentru timpul de execuie a procedurii Construiete-Heap:

blg nc l
n m
blg nc
X X h
O(h) = O n . (7.2)
2h+1 2h
h=0 h=0

Ultima nsumare poate fi evaluat prin nlocuirea x = 1/2 n formula (3.6). Obinem

X h 1/2
= = 2. (7.3)
2h (1 1/2)2
h=0

Astfel, timpul de execuie al procedurii Construiete-Heap poate fi estimat ca fiind:


!
blg nc
X h X h
O n =O n = O(n). (7.4)
2h 2h
h=0 h=0

De aici rezult c se poate construi un heap dintr-un vector ntr-un timp liniar.

Exerciii
7.3-1 Utiliznd ca model figura 7.3, ilustrai modul de funcionare al procedurii Construiete-
Heap pentru vectorul A = h5, 3, 17, 10, 84, 19, 6, 22, 9i.

7.3-2 De ce trebuie micorat variabila de control i a ciclului n linia 2 a procedurii


Construiete-Heap de la blungime[A]/2c la 1, n loc s fie mrit de la 1 la blungime[A]/2c?

7.3-3 ? Artai c, ntr-un heap de nlime h avnd n elemente, numrul nodurilor este cel
mult dn/2h+1 e.

7.4. Algoritmul heapsort


Algoritmul heapsort ncepe cu apelul procedurii Construiete-Heap n scopul transformrii
vectorului de intrare A[1..n] n heap, unde n = lungime[A]. Deoarece cel mai mare element al
vectorului este ataat nodului rdcin A[1], acesta va ocupa locul definitiv n vectorul ordonat
prin interschimbarea sa cu A[n]. n continuare, excluznd din heap cel de-al n-lea element (i
micornd cu 1 dimesiune-heap[A]), restul de A[1..(n 1)] elemente se pot transforma uor n
heap, deoarece subarborii nodului rdcin au proprietatea de heap (7.1), cu eventuala excepie
a elementului ajuns n nodul rdcin.
Heapsort(A)
1: Construiete-Heap(A)
2: pentru i lungime[A], 2 execut
3: schimb A[1] A[i]
4: dimesiune-heap[A] dimesiune-heap[A] 1
5: Reconstituie-Heap(A, 1)
126 Capitolul 7 Heapsort

Apelnd procedura Reconstituie-Heap(A, 1) se restabilete proprietatea de heap pentru


vectorul A[1..(n 1)]. Acest procedeu se repet micornd dimensiunea heap-ului de la n 1 la
2.
Figura 7.4 ilustreaz, pe un exemplu, modul de funcionare a procedurii Heapsort, dup
ce n prealabil datele au fost transformate n heap. Fiecare heap reprezint starea iniial la
nceputul pasului iterativ (linia 2 din ciclul pentru).
Timpul de execuie al procedurii Heapsort este O(n lg n), deoarece procedura Constru-
iete-Heap se execut ntr-un timp O(n), iar procedura Reconstituie-Heap, apelat de n 1
ori, se execut n timpul O(lg n).

Exerciii
7.4-1 Utiliznd ca model figura 7.4, ilustrai modul de funcionare al procedurii Heapsort
pentru vectorul A = h5, 13, 2, 25, 7, 17, 20, 8, 4i.

7.4-2 Care este timpul de execuie al algoritmului heapsort n cazul unui vector A de dimensiune
n, ordonat cresctor? Dar n cazul unui vector ordonat descresctor?

7.4-3 Artai c timpul de execuie al algoritmului heapsort este (n lg n).

7.5. Cozi de prioriti


Heapsort este un algoritm excelent, dar o implementare bun a algoritmului de sortare rapid,
algoritm prezentat n capitolul 8, se poate dovedi de multe ori mai eficient. n schimb, structura
de date heap este foarte util. n aceast seciune vom prezenta una din cele mai frecvente
aplicaii ale unui heap: utilizarea lui sub forma unei cozi de prioriti.
Coada de prioriti este o structur de date care conine o mulime S de elemente, fiecare
avnd asociat o valoare numit cheie. Asupra unei cozi de prioriti se pot efectua urmtoarele
operaii.
Insereaz(S, x) insereaz elementul x n mulimea S. Aceast operaie poate fi scris n felul
urmtor: S S {x}.
Maxim(S) returneaz elementul din S avnd cheia cea mai mare.
Extrage-Max(S) elimin i returneaz elementul din S avnd cheia cea mai mare.
O aplicaie a cozilor de prioriti const n planificarea lucrrilor pe calculatoare partajate.
Sarcinile care trebuie efectuate i prioritile relative se memoreaz ntr-o coad de prioritate.
Cnd o lucrare este terminat sau ntrerupt, procedura Extrage-Max va selecta lucrarea
avnd prioritatea cea mai mare dintre lucrrile n ateptare. Cu ajutorul procedurii Inserare,
n coad poate fi introdus oricnd o lucrare nou.
O coad de prioriti poate fi utilizat i n simularea unor evenimente controlate. Din coad
fac parte evenimentele de simulat, fiecruia atandu-i-se o cheie reprezentnd momentul cnd va
avea loc evenimentul. Evenimentele trebuie simulate n ordinea desfurrii lor n timp, deoarece
simularea unui eveniment poate determina necesitatea simulrii altuia n viitor. n cazul acestei
aplicaii, este evident c ordinea evenimentelor n coada de prioriti trebuie inversat, iar
7.5. Cozi de prioriti 127

Figura 7.4 Modul de funcionare a algoritmului Heapsort. (a) Structura de date heap, imediat dup
construirea sa de ctre procedura Construiete-Heap. (b)-(j) Heap-ul, imediat dup cte un apel al
procedurii Reconstituie-Heap (linia 5 n algoritm). Figura reprezint valoarea curent a variabilei i.
Din heap fac parte doar nodurile din cercurile nehaurate. (k) Vectorul A ordonat, obinut ca rezultat.
128 Capitolul 7 Heapsort

procedurile Maxim i Extrage-Max se vor nlocui cu Minim i Extrage-Min. Programul


de simulare va determina urmtorul eveniment cu ajutorul procedurii Extrage-Min, iar dac
va trebui introdus un nou element n ir, se va apela procedura Inserare.
Rezult n mod firesc faptul c o coad de prioriti poate fi implementat utiliznd un heap.
Operaia Maxim-Heap va determina n timpul (1) cel mai mare element al heap-ului care, de
fapt, este valoarea A[1]. Procedura Extrage-Max-Din-Heap este similar structurii repetitive
pentru (liniile 35) din procedura Heapsort:
Extrage-Max-Din-Heap(A)
1: dac dimesiune-heap[A] < 1 atunci
2: eroare depire inferioar heap
3: max A[1]
4: A[1] A[dimesiune-heap[A]]
5: dimesiune-heap[A] dimesiune-heap[A] 1
6: Reconstituie-Heap(A, 1)
7: returneaz maxim

Timpul de execuie al procedurii Extrage-Max-Din-Heap este O(lg n), deoarece conine doar
civa pai, care se execut n timp constant nainte s se execute procedura Reconstituie-
Heap, care necesit un timp de O(lg n).
Procedura Insereaz-n-Heap insereaz un nod n heap-ul A. La prima expandare a heap-
ului se adaug o frunz arborelui. Apoi, la fel ca n structura repetitiv de inserare (liniile 57)
din Sortare-Prin-Inserare (din seciunea 1.1), se traverseaz un drum pornind de la aceast
frunz ctre rdcin, n scopul gsirii locului definitiv al noului element.
Insereaz-n-Heap(A, cheie)
1: dimesiune-heap[A] dimesiune-heap[A] + 1
2: i dimesiune-heap[A]
3: ct timp i > 1 i A[Printe(i)] < cheie execut
4: A[i] A[Printe(i)]
5: i Printe(i)
6: A[i] cheie

n figura 7.5 este ilustrat un exemplu al operaiei Insereaz-n-Heap. Timpul de execuie


al procedurii Insereaz-n-Heap, pentru un heap avnd n elemente, este O(lg n), deoarece
drumul parcurs de la noua frunz ctre rdcin are lungimea O(lg n).
n concluzie, pe un heap se poate efectua orice operaie specific unei cozi de prioriti,
definit pe o mulime avnd n elemente, ntr-un timp O(lg n).

Exerciii
7.5-1 Utiliznd ca model figura 7.5, ilustrai operaia Insereaz-n-Heap(A, 10) pentru heap-
ul A = h15, 13, 9, 5, 12, 8, 7, 4, 0, 6, 2, 1i.

7.5-2 Dat fiind heap-ul A = h15, 13, 9, 5, 12, 8, 7, 4, 0, 6, 2, 1i, ilustrai operaia Extrage-Max-
Din-Heap.
7.5. Cozi de prioriti 129

Figura 7.5 Operaia Insereaz-n-Heap. (a) Heap-ul din figura 7.4(a) nainte de inserarea nodului
avnd cheia 15. (b) Se adaug arborelui o frunz nou. (c) Se scufund valorile de pe drumul dintre
frunz i rdcin pn la gsirea nodului corespunztor cheii 15. (d) Se insereaz cheia 15.

7.5-3 Artai cum se poate implementa o list de tip FIFO cu ajutorul unei cozi de prioriti.
Artai cum se poate implementa o stiv cu ajutorul unei cozi de prioriti. (Listele FIFO i
stivele vor fi definite n seciunea 11.1.)

7.5-4 Scriei o implementare a procedurii Heap-Cu-Chei-Cresctoare(A, i, k) de timp


O(lg n), care realizeaz atribuirea A[i] max(A[i], k), i actualizeaz structura heap n mod
corect.

7.5-5 Operaia terge-Din-Heap(A, i) terge elementul ataat nodului i din heap-ul A. Gsii
o implementare pentru operaia terge-Din-Heap care se execut pentru un heap avnd n
elemente ntr-un timp O(lg n).

7.5-6 Gsii un algoritm de timp O(n lg k) pentru a interclasa k liste ordonate, unde n este
numrul total de elemente din listele de intrare. (Indicaie: se utilizeaz un heap)
130 Capitolul 7 Heapsort

Probleme
7-1 Construirea unui heap prin inserare
Procedura Construiete-Heap, din seciunea 7.3, poate fi implementat folosind, n mod
repetat, procedura Inserare-n-Heap, n scopul inserrii elementelor n heap. Fie urmtoarea
implementare:
Construiete-Heap0 (A)
1: dimesiune-heap[A] 1
2: pentru i 2, lungime[A] execut
3: Insereaz-n-Heap(A, A[i])

a. Pentru date de intrare identice, procedurile Construiete-Heap i Construiete-


Heap0 construiesc acelai heap? Demonstrai sau gsii contraexemple.
b. Artai c, n cazul cel mai defavorabil, procedura Construiete-Heap0 cere un timp
(n lg n) pentru a construi un heap avnd n elemente.

7-2 Analiza heap-urilor d-are


Un heap d-ar este asemntor unui heap binar, dar nodurile nu au doi ci d descendeni.

a. Cum se poate reprezenta un heap d-ar sub forma unui vector?


b. Care este nlimea (n funcie de n i d) a unui heap d-ar, avnd n elemente?

c. Descriei o implementare eficient pentru operaia Extrage-Max. Analizai timpul de


execuie n funcie de n i d.
d. Descriei o implementare eficient pentru operaia Inserare. Analizai timpul de execuie
n funcie de n i d.
e. Descriei o implementare eficient pentru operaia Heap-Cu-Chei-Cresctoare(A, i, k)
care realizeaz A[i] max(A[i], k) i actualizeaz structura heap n mod corect. Analizai
timpul de execuie n funcie de d i n.

Note bibliografice
Algoritmul heapsort a fost inventat de Williams [202], care a descris i modul de implementare
a unei cozi de prioriti printr-un heap. Procedura Construiete-Heap a fost propus de Floyd
[69].
8 Sortarea rapid

Sortarea rapid este un algoritm de sortare care, pentru un ir de n elemente, are un timp
de execuie (n2 ), n cazul cel mai defavorabil. n ciuda acestei comportri proaste, n cazul cel
mai defavorabil, algoritmul de sortare rapid este deseori cea mai bun soluie practic, deoarece
are o comportare medie remarcabil: timpul su mediu de execuie este (n lg n), i constanta
ascuns n formula (n lg n) este destul de mic. Algoritmul are avantajul c sorteaz pe loc
(n spaiul alocat irului de intrare) i lucreaz foarte bine chiar i ntr-un mediu de memorie
virtual.
n seciunea 8.1 sunt descrii algoritmul i un subalgoritm important, folosit de sortarea rapid
pentru partiionare. Deoarece comportarea algoritmului de sortare rapid este foarte complex,
vom ncepe studiul performanei lui cu o discuie intuitiv n seciunea 8.2, i lsm analiza
precis la sfritul capitolului. n seciunea 8.3 sunt prezentate dou variante ale algoritmului
de sortare rapid, care utilizeaz un generator de numere aleatoare. Aceti algoritmi aleatori
au multe proprieti interesante. Timpul lor mediu de execuie este bun i nu se cunosc date
de intrare particulare pentru care s aib comportarea cea mai proast. O variant aleatoare a
algoritmului de sortare rapid este studiat n seciunea 8.4 i se demonstreaz c timpul lui de
execuie, n cazul cel mai defavorabil, este O(n2 ), iar timpul mediu O(n lg n).

8.1. Descrierea sortrii rapide


Algoritmul de sortare rapid, ca de altfel i algoritmul de sortare prin interclasare, se bazeaz
pe paradigma divide i stpnete, introdus n seciunea 1.3.1. Iat un proces divide i
stpnete n trei pai, pentru un subir A[p..r].

Divide: irul A[p..r] este mprit (rearanjat) n dou subiruri nevide A[p..q] i A[q + 1..r],
astfel nct fiecare element al subirului A[p..q] s fie mai mic sau egal cu orice element al
subirului A[q + 1..r]. Indicele q este calculat de procedura de partiionare.

Stpnete: Cele dou subiruri A[p..q] i A[q + 1..r] sunt sortate prin apeluri recursive ale
algoritmului de sortare rapid.

Combin: Deoarece cele dou subiruri sunt sortate pe loc, nu este nevoie de nici o combinare,
irul A[p..r] este ordonat.

Descrierea algoritmului este urmtoarea:


Quicksort(A, p, r)
1: dac p < r atunci
2: q Partiie(A, p, r)
3: Quicksort(A, p, q)
4: Quicksort(A, q + 1, r)

Pentru ordonarea ntregului ir A, iniial se apeleaz Quicksort(A, 1, lungime[A]).


132 Capitolul 8 Sortarea rapid

Partiionarea irului
Cheia algoritmului este procedura Partiie, care rearanjeaz pe loc subirul A[p..r].
Partiie(A, p, r)
1: x A[p]
2: i p 1
3: j r + 1
4: ct timp adevrat execut
5: repet
6: j j1
7: pn cnd A[j] x
8: repet
9: ii+1
10: pn cnd A[i] x
11: dac i < j atunci
12: interschimb A[i] A[j]
13: altfel
14: returneaz j

n figura 8.1 este ilustrat modul de funcionare a procedurii Partiie. nti se selecteaz un
element x = A[p] din irul A[p..r], care va fi elementul pivot, n jurul cruia se face partiionarea
irului A[p..r]. Apoi, dou subiruri A[p..i] i A[j..r] cresc la nceputul i respectiv, sfritul irului
A[p..r], astfel nct fiecare element al irului A[p..i] s fie mai mic sau egal cu x, i orice element
al irului A[j..r], mai mare sau egal cu x. La nceput i = p 1 i j = r + 1, deci cele dou
subiruri sunt vide.
n interiorul ciclului ct timp, n liniile 57, indicele j se decrementeaz, iar i se incremen-
teaz pn cnd A[i] x A[j]. Presupunnd c inegalitile de mai sus sunt stricte, A[i] este
prea mare ca s aparin primului subir (cel de la nceput), iar A[j] prea mic ca s aparin
celui de al doilea subir (cel de la sfrit). Astfel, interschimbnd A[i] cu A[j] (linia 12), cele
dou pri cresc. (Interschimbarea se poate face i n cazul n care avem inegaliti stricte.)
Ciclul ct timp se repet pn cnd inegalitatea i j devine adevrat. n acest moment,
ntregul ir A[p..r] este partiionat n dou subiruri A[p..q] i A[q + 1..r], astfel nct p q < r
i nici un element din A[p..q] nu este mai mare dect orice element din A[q + 1..r]. Procedura
returneaz valoarea q = j.
De fapt, procedura de partiionare execut o operaie simpl: pune elementele mai mici dect
x n primul subir, iar pe cele mai mari dect x n subirul al doilea. Exist cteva particulariti
care determin o comportare interesant a procedurii Partiie. De exemplu, indicii i i j nu
depesc niciodat marginile vectorului A[p..r], dar acest lucru nu se vede imediat din textul
procedurii. Un alt exemplu: este important ca elementul A[p] s fie utilizat drept element pivot
x. n schimb, dac se folosete A[r] ca element pivot, i, ntmpltor, A[r] este cel mai mare
element al vectorului A[p..r], atunci Partiie returneaz procedurii Quicksort valoarea q =
r, i procedura intr ntr-un ciclu infinit. Problema 8-1 cere s se demonstreze corectitudinea
procedurii Partiie.
Timpul de execuie al procedurii Partiie, n cazul unui vector A[p..r], este (n), unde
n = r p + 1 (vezi exerciiul 8.1-3.).
8.2. Performana algoritmului de sortare rapid 133

Figura 8.1 Operaiile efectuate de procedura Partiie pe un exemplu. Elementele haurate n gri
deschis sunt deja plasate n poziiile lor corecte, iar cele haurate nchis nc nu. (a) irul de intrare,
cu valorile iniiale ale variabilelor i i j, care punctez n afara irului. Vom face partiionarea n jurul
elementului x = A[p] = 5. (b) Poziiile lui i i j n linia 11 a algoritmului, dup prima parcurgere a
ciclului ct timp. (c) Rezultatul schimbului de elemente descris n linia 12. (d) Valorile lui i i j n
linia 11 dup a doua parcurgere a ciclului ct timp. (e) Valorile lui i i j dup a treia i ultima iteraie
a ciclului ct timp. Procedura se termin deoarece i j i valoarea returnat este q = j. Elementele
irului pn la A[j], inclusiv, sunt mai mici sau egale cu x = 5, iar cele de dup A[j], sunt toate mai
mici sau egale cu x = 5.

Exerciii
8.1-1 Folosind figura 8.1 drept model, s se ilustreze operaiile procedurii Partiie n cazul
vectorului A = h13, 19, 9, 5, 12, 8, 7, 4, 11, 2, 6, 21i.

8.1-2 Ce valoare a lui q returneaz procedura Partiie, dac toate elementele vectorului A[p..r]
sunt egale.

8.1-3 S se argumenteze, pe scurt, afirmaia c timpul de execuie al procedurii Partiie,


pentru un vector de n elemente, este (n).

8.1-4 Cum trebuie modificat procedura Quicksort pentru a ordona descresctor?

8.2. Performana algoritmului de sortare rapid


Timpul de execuie al algoritmului de sortare rapid depinde de faptul c partiionarea este
echilibrat sau nu, iar acesta din urm de elementele alese pentru partiionare. Dac partiionarea
este echilibrat, algoritmul asimptotic este la fel de rapid ca sortarea prin interclasare. n cazul
n care partiionarea nu este echilibrat, algoritmul se execut la fel de ncet ca sortarea prin
inserare. n aceast seciune vom investiga, fr rigoare matematic, performana algoritmului
de sortare rapid n cazul partiionrii echilibrate.
134 Capitolul 8 Sortarea rapid

Figura 8.2 Arborele de recursivitate pentru Quicksort cnd procedura Partiie pune ntotdeauna
ntr-o parte a vectorului numai un singur element (cazul cel mai defavorabil). Timpul de execuie n
acest caz este (n2 ).

Partiionarea n cazul cel mai defavorabil


Comportarea cea mai defavorabil a algoritmului de sortare rapid apare n situaia n care
procedura de partiionare produce un vector de n1 elemente i unul de 1 element. (Demonstraia
se face n seciunea 8.4.1) S presupunem c aceast partiionare dezechilibrat apare la fiecare
pas al algoritmului. Deoarece timpul de partiionare este de (n), i T (1) = (1), formula
recursiv pentru timpul de execuie a algoritmului de sortare rapid este:

T (n) = T (n 1) + (n).

Pentru evaluarea formulei de mai sus, observm c T (1) = (1), apoi iterm formula:
n
n !
X X
T (n) = T (n 1) + (n) = (k) = k = (n2 ).
k=1 k=1
Pn
Ultima egalitate se obine din observaia c k=1 k este o progresie aritmetic (3.2). n figura
8.2 este ilustrat arborele de recursivitate pentru acest cel mai defavorabil caz al algoritmului de
sortare rapid. (Vezi seciunea 4.2 pentru alte detalii privind arborii recursivi.)
Dac partiionarea este total dezechilibrat la fiecare pas recursiv al algoritmului, atunci
timpul de execuie este (n2 ). Deci timpul de execuie, n cazul cel mai defavorabil, nu este
mai bun dect al algoritmului de sortare prin inserare. Mai mult, timpul de execuie este (n2 )
chiar i n cazul n care vectorul de intrare este ordonat caz n care algoritmul de sortare prin
inserare are timpul de execuie O(n).

Partiionarea n cazul cel mai favorabil


Dac algoritmul de partiionare produce doi vectori de n/2 elemente, algoritmul de sortare
rapid lucreaz mult mai repede. Formula de recuren n acest caz este:

T (n) = 2T (n/2) + (n)


8.2. Performana algoritmului de sortare rapid 135

Figura 8.3 Arborele de recuren pentru Quicksort cnd procedura Partiie produce ntotdeauna
pri egale (cazul cel mai favorabil). Timpul de execuie rezultat este (n lg n).

a crei soluie este T (n) = (n lg n) (dup cazul 2 al teoremei 4.1). Deci partiionarea cea mai
bun produce un algoritm de sortare mult mai rapid. n figura 8.3 se ilustreaz arborele de
recursivitate pentru acest cel mai favorabil caz.

Partiionarea echilibrat
Analiza din seciunea 8.4 va arta c timpul mediu de execuie a algoritmului de sortare
rapid este mult mai apropiat de timpul cel mai bun dect de timpul cel mai ru. Pentru a
nelege de ce este aa, ar trebui s studiem efectul partiionrii echilibrate asupra formulei
recursive care descrie timpul de execuie.
S presupunem c procedura de partiionare produce ntotdeauna o mprire n proporie de
9 la 1, care la prima vedere pare a fi o partiionare dezechilibrat. n acest caz, formula recursiv
pentru timpul de execuie al algoritmului de sortare rapid este:
T (n) = T (9n/10) + T (n/10) + n
unde, pentru simplificare, n loc de (n) s-a pus n. Arborele de recuren corespunztor se
gsete n figura 8.4. S observm c la fiecare nivel al arborelui costul este n pn cnd la
adncimea log10 n = (lg n) se atinge o condiie iniial. n continuare, la celelalte niveluri,
costul nu depete valoarea n. Apelul recursiv se termin la adncimea log10/9 n = (lg n).
Costul total al algoritmului de sortare rapid este deci (n lg n). Ca urmare, cu o partiionare
n proporie de 9 la 1 la fiecare nivel al partiionrii (care intuitiv pare a fi total dezechilibrat),
algoritmul de sortare rapid are un timp de execuie de (n lg n) asimptotic acelai ca n cazul
partiionrii n dou pri egale. De fapt, timpul de execuie va fi O(n lg n) i n cazul partiionrii
ntr-o proporie de 99 la 1. La orice partiionare ntr-o proporie constant, adncimea arborelui
de recursivitate este (lg n) i costul, la fiecare nivel, este O(n). Deci timpul de execuie este
(n lg n) la orice partiionare ntr-o proporie constant.

Intuirea comportrii medii


Pentru a avea o idee clar asupra comportrii medii a algoritmului de sortare rapid, trebuie
s facem presupuneri asupra frecvenei anumitor intrri. Cea mai evident presupunere este c
136 Capitolul 8 Sortarea rapid

Figura 8.4 Arborele de recuren pentru Quicksort, cnd procedura Partiie produce ntotdeauna
pri n proporie de 9 la 1, rezultnd un timp de execuie de (n lg n).

toate permutrile elementelor de intrare sunt la fel de probabile. Vom discuta aceast presupunere
n seciunea urmtoare, aici vom exploata doar cteva variante.
n situaia n care algoritmul de sortare rapid lucreaz pe o intrare aleatoare, probabil c nu
va partiiona la fel la fiecare nivel, cum am presupus n discuiile anterioare. Este de ateptat ca
unele partiionri s fie echilibrate, altele nu. De exemplu, exerciiul 8.2-5 cere s se demonstreze
c procedura Partiie produce n 80% din cazuri o partiionare mai echilibrat dect proporia
de 9 la 1, i, numai n 20% din cazuri, una mai puin echilibrat.
n cazul mediu, procedura Partiie produce un amestec de partiionri bune i rele. ntr-
un arbore de recuren pentru cazul mediu al procedurii Partiie, partiionrile bune i rele
sunt distribuite aleator. S presupunem, totui, pentru simplificare, c partiionrile bune i rele
alterneaz pe niveluri, i c partiionrile bune corespund celui mai bun caz, iar cele rele celui
mai defavorabilcaz. n figura 8.5 sunt prezentate partiionrile la dou niveluri consecutive n
arborele de recursivitate. Costul partiionrii la rdcina arborelui este n, iar vectorii obinui
sunt de dimensiune n 1 i 1: cazul cel mai defavorabil. La nivelul urmtor, vectorul de n 1
elemente se mparte n doi vectori de (n 1)/2 elemente fiecare, potrivit cazului celui mai bun.
S presupunem c pentru un vector de dimensiune 1 (un element) costul este 1.
Combinarea unei partiionri rele i a uneia bune produce trei vectori de dimensiune 1,
(n 1)/2 i respectiv (n 1)/2, cu un cost total de 2n 1 = (n). Evident, aceast situaie nu
este mai rea dect cea prezentat n figura 8.5(b), adic cea cu un singur nivel, care produce un
vector de (n 1)/2 + 1 elemente i unul de (n 1)/2 elemente, cu un cost total de n = (n).
Totui, situaia din urm este aproape echilibrat, cu siguran mult mai bun dect proporia 9
la 1. Intuitiv, o partiionare defavorabil de un cost (n) poate fi absorbit de una bun tot de un
cost (n), i partiionarea rezultat este favorabil. Astfel timpul de execuie al algoritmului de
sortare rapid, cnd partiionrile bune i rele alterneaz, este acelai ca n cazul partiionrilor
bune: tot O(n lg n), doar constanta din notaia O este mai mare. O analiz riguroas a cazului
mediu se va face n seciunea 8.4.2.
8.3. Variantele aleatoare ale sortrii rapide 137

Figura 8.5 (a) Dou niveluri ale arborelui de recurent pentru algoritmul de sortare rapid. Parti-
ionarea la nivelul rdcinii consum n uniti de timp i produce o partiionare proast: doi vectori
de dimensiune 1 i n 1. Partiionarea unui subir de n 1 elemente necesit n 1 uniti de timp i
este o partiionare bun: produce dou subiruri de (n 1)/2 elemente fiecare. (b) Un singur nivel al
arborelui de recuren care este mai ru dect nivelurile combinate de la (a), totui foarte bine echilibrat.

Exerciii
8.2-1 Demonstrai c timpul de execuie al algoritmului Quicksort, n cazul unui vector A cu
toate elementele egale ntre ele, este (n lg n).

8.2-2 Demonstrai c, n cazul unui vector A avnd n elemente distincte, ordonate descresctor,
timpul de execuie al algoritmului Quicksort este (n2 ).

8.2-3 Bncile, de obicei, nregistreaz tranzaciile pe un cont dup data tranzaciilor, dar
multora dintre clieni le place s primeasc extrasele de cont, ordonate dup numrul cecurilor,
deoarece ei primesc cecurile grupate de la comerciani. Problema convertirii ordonrii dup data
tranzaciei n ordonare dup numrul de cec este problema sortrii unui vector aproape ordonat.
S se argumenteze de ce, n acest caz, algoritmul Sorteaz-Prin-Inserie este mai bun dect
algoritmul Quicksort.

8.2-4 S presupunem c partiionarea la fiecare nivel, n cadrul algoritmului de sortare rapid,


se face ntr-o proporie de 1 la , unde 0 < 1/2 i este constant. Demonstrai c, n
arborele de recuren, adncimea minim a unui nod terminal este aproximativ lg n/ lg , pe
cnd adncimea maxim este aproximativ lg n/ lg(1 ). (Nu se va ine cont de rotunjiri.)

8.2-5 ? Argumentai afirmaia c, pentru orice constant 0 < 1/2, probabilitatea ca pentru
o intrare aleatoare procedura Partiie s produc o partiionare mai echilibrat dect proporia
1 la , este aproximativ 1 2. Pentru ce valoare a lui partiionarea mai echilibrat are
anse egale cu cea mai puin echilibrat?

8.3. Variantele aleatoare ale sortrii rapide


n analiza comportrii medii a algoritmului de sortare rapid, am presupus c toate permut-
rile elementelor de intrare sunt la fel de probabile. Muli consider c, dac aceast presupunere
este adevrat, algoritmul de sortare rapid, este cea mai bun soluie pentru a sorta vectori de
dimensiuni mari. Totui, nu ne putem atepta ca, n practic aceasta s se ntmple ntotdeauna
138 Capitolul 8 Sortarea rapid

aa (vezi exerciiul 8.2-3). n aceast seciune, vom introduce noiunea de algoritm aleator i vom
prezenta dou variante aleatoare ale algoritmului de sortare rapid, care fac inutil presupunerea
c toate permutrile elementelor de intrare sunt la fel de probabile.
O alternativ, la a presupune o distribuie de date de intrare, este de a impune o astfel de
distribuie. De exemplu, s presupenem c, nainte s sorteze vectorul de intrare, algoritmul
de sortare rapid permut aleator elementele pentru a asigura astfel proprietatea c fiecare
permutare are aceeai probabilitate. (Exerciiul 8.3-4 cere scrierea unui algoritm care permut
aleator elementele unui vector de dimensiune n n O(n) uniti de timp.) Aceast modificare
nu mbuntete timpul de execuie a algoritmului n cazul cel mai defavorabil, dar asigur ca
timpul de execuie s nu depind de ordinea elementelor de intrare.
Un algoritm se numete aleator dac comportarea lui depinde nu numai de valorile de
intrare, ci i de valorile produse de un generator de numere aleatoare. Vom presupune
c dispunem de un generator de numere aleatoare numit Random. Un apel al procedurii
Random(a, b) produce un numr ntreg ntre a i b inclusiv. Fiecare numr ntreg din acest
interval [a, b] este la fel de probabil. De exemplu, Random(0,1) produce 0 i 1 cu aceeai proba-
bilitate 1/2. Fiecare ntreg generat de Random este independent de valorile generate anterior.
Ne-am putea imagina c Random este un zar cu (b a + 1) fee. (Majoritatea mediilor de
programare posed un generator de numere pseudoaleatoare, un algoritm determinist care
produce numere care par a fi aleatoare.)
Aceast variant a algoritmului de sortare rapid (ca de altfel muli ali algoritmi aleatori) are
interesanta proprietate c, practic, pentru nici o intrare nu are comportarea cea mai defavorabil.
Din contr, cazul cel mai defavorabil depinde de generatorul de numere aleatoare. Chiar dac
dorim, nu reuim s generm un vector de intrare prost, deoarece permutarea aleatoare face ca
ordinea datelor de intrare s fie irelevant. Algoritmul aleator poate avea o comportare proast
numai dac generatorul de numere aleatoare produce o intrare nefericit. n exerciiul 13.4-
4 se arat c pentru aproape toate permutrile elementelor de intrare, algoritmul de sortare
rapid are o comportare similar cu cazul mediu i aceast comportare este apropiat de cea
mai defavorabil doar pentru foarte puine permutri.
O strategie aleatoare este de obicei util cnd exist multe moduri n care un algoritm se poate
executa, dar este dificil s determinm un mod care s fie cu siguran bun. Dac multe din aceste
alternative sunt bune, alegerea pur i simplu a uneia, la ntmplare, poate reprezenta o strategie
bun. Deseori, n timpul execuiei sale, un algoritm trebuie s ia multe decizii. Dac beneficiile
unei decizii bune sunt mult mai mari dect costurile unor decizii rele, o selecie aleatoare de decizii
bune i rele poate determina un algoritm eficient. n seciunea 8.2 am artat c o combinaie de
partiionri bune i rele asigur un timp de execuie bun pentru algoritmul de sortare rapid, i
acest fapt sugereaz c i algoritmul aleator va avea o comportare bun.
Prin modificarea procedurii Partiie, se poate obine o variant nou a algoritmului de
sortare rapid care folosete aceast strategie de alegere aleatoare. La fiecare pas al sortrii
rapide, nainte de partiionarea vectorului, interschimbm elementul A[p] cu un element ales
aleator din vectorul A[p..r]. Aceast modificare asigur ca elementul pivot x = A[p] s fie,
cu aceeai probabilitate, orice element dintre cele r p + 1 elemente ale vectorului. Astfel,
partiionarea vectorului de intrare poate fi, n medie, rezonabil de echilibrat. Algoritmul aleator,
bazat pe permutarea elementelor de intrare, are i el o comportare medie bun, dar ceva mai
dificil de studiat dect aceast versiune.
Modificrile asupra procedurilor Partiie i Quicksort sunt minore. n noua procedur de
partiionare inserm pur i simplu interschimbarea celor dou elemente nainte de partiionare:
8.4. Analiza algoritmului de sortare rapid 139

Partiie-Aleatoare(A, p, r)
1: i Random(p, r)
2: interschimb A[p] A[i]
3: returneaz Partiie (A, p, r)

Noul algoritm de sortare rapid folosete n loc de Partiie procedura Partiie-Aleatoare:


Quicksort-Aleator(A, p, r)
1: dac p < r atunci
2: q Partiie-Aleatoare(A, p, r)
3: Quicksort-Aleator(A, p, q)
4: Quicksort-Aleator(A, q + 1, r)

Analiza algoritmului se va face n seciunea urmtoare.

Exerciii
8.3-1 De ce, n loc s studiem comportarea cea mai defavorabil a unui algoritm aleator, studiem
comportarea medie?

8.3-2 De cte ori se apeleaz generatorul de numere aleatoare Random n timpul execuiei
procedurii Quicksort-Aleator n cazul cel mai defavorabil? Cum se schimb rspunsul n
cazul cel mai favorabil?

8.3-3 ? Descriei o implementare a algoritmului Random(a, b), care folosete numai aruncri
de monede perfecte. Care va fi timpul mediu de execuie a procedurii?

8.3-4 ? Scriei un algoritm aleator care ruleaz n (n) uniti de timp, are ca intrare un vector
A[1..n] i produce la ieire o permutare a elementelor de intrare.

8.4. Analiza algoritmului de sortare rapid


Rezultatul studiului intuitiv din seciunea 8.2 ne face s credem c algoritmul de sortare
rapid are o comportare bun. n aceast seciune vom face o analiz mai riguroas. ncepem cu
analiza cazului celui mai defavorabil, att pentru algoritmul Quicksort ct i pentru algoritmul
Quicksort-Aleator, i terminm cu analiza cazului mediu pentru algoritmul Quicksort-
Aleator.

8.4.1. Analiza celui mai defavorabil caz


Am vzut, n seciunea 8.2, c mprirea cea mai rea la fiecare nivel ne conduce la timpul de
execuie al algoritmului (n2 ), care, intuitiv, reprezint comportarea n cazul cel mai defavorabil.
n continuare vom demonstra aceast afirmaie.
Folosind metoda substituiei (vezi seciunea 4.1), se poate demonstra c timpul de execuie
al algoritmului Quicksort este O(n2 ). Fie T (n) timpul de execuie al algoritmului de sortare
140 Capitolul 8 Sortarea rapid

rapid, n cazul cel mai defavorabil, pentru o intrare de dimensiunea n. Avem urmtoarea formul
de recuren
T (n) = max (T (q) + T (n q)) + (n), (8.1)
1qn1

unde parametrul q parcurge valorile ntre 1 i n 1, deoarece procedura Partiie produce dou
subiruri, avnd fiecare, cel puin un element. Presupunem c T (n) cn2 , pentru o constant c.
nlocuind n formula (8.1), obinem urmtoarele:
T (n) max (cq 2 + c(n q)2 ) + (n) = c max (q 2 + (n q)2 ) + (n).
1qn1 1qn1

Expresia q 2 + (n q)2 atinge valoarea sa maxim n domeniul de valori 1 q n 1 la una


din extreme, deoarece derivata a doua, dup q a expresiei, este pozitiv (vezi exerciiul 8.4-2).
Deci, avem
max (q 2 + (n q)2 ) 12 + (n 1)2 = n2 2(n 1).
1qn1

Continund majorarea lui T (n), obinem:


T (n) cn2 2c(n 1) + (n) cn2 ,
deoarece constanta c poate fi aleas suficient de mare, astfel nct termenul 2c(n 1) s domine
termenul (n). Rezult c timpul de execuie (cel mai defavorabil) al algoritmului de sortare
rapid este (n2 ).

8.4.2. Analiza cazului mediu


Am explicat deja, intuitiv, de ce timpul mediu de execuie al algoritmului Quicksort-
Aleator este (n lg n): dac procedura Partiie-Aleatoare mparte vectorul, la fiecare nivel,
n aceeai proporie, atunci adncimea arborelui de recuren este (lg n), i timpul de execuie la
fiecare nivel este (n). Pentru a putea analiza mai exact timpul mediu de execuie al algoritmului
Quicksort-Aleator, va trebui s nelegem esena procedurii de partiionare. n continuare,
vom putea gsi o formul de recuren pentru timpul mediu de execuie, necesar pentru sortarea
unui vector de dimensiune n. Ca parte a procesului de rezolvare a recurenei, vom gsi margini
tari pentru o sum interesant.

Analiza partiionrii
La nceput, facem cteva observaii asupra procedurii Partiie. Cnd n linia 3 a procedurii
Partiie-Aleatoare este apelat procedura Partiie, elementul A[p] este deja interschimbat
cu un element ales aleator din vectorul A[p..r]. Pentru simplificare, s presupunem c toate
elementele de intrare sunt distincte. Dac elementele de intrare nu sunt distincte, timpul mediu
de execuie al algoritmului rmne tot O(n lg n), dar acest caz necesit o analiz ceva mai
complex.
Prima noastr observaie este c valoarea q, returnat de procedura Partiie, depinde numai
de rangul elmentului x = A[p] n vectorul A[p..r]. (Rangul unui element ntr-o mulime este
egal cu numrul elementelor care sunt mai mici sau egale cu el.) Dac notm cu n = r p + 1
numrul elementelor vectorului A[p..r], i interschimbm elementul x = A[p] cu un element ales
8.4. Analiza algoritmului de sortare rapid 141

aleator din vectorul A[p..r], probabilitatea ca rang(x) = i (unde i = 1, 2, . . . , n) este egal cu


1/n.
Vom calcula, n continuare, probabilitatea diferitelor rezultate ale procedurii de partiionare.
Dac rang(x) = 1, atunci, n procedura Partiie, la prima execuie a ciclului ct timp din
liniile 414, variabilele i i j vor primi aceeai valoare p. Deci, cnd procedura returneaz valoarea
q = j, n primul subir, singurul element va fi A[p]. Probabilitatea acestui caz este 1/n, deoarece
aceasta este probabiltatea ca rang(x) s fie egal cu 1.
Dac rang(x) 2, atunci, exist cel puin un element care este mai mic dect x = A[p]. n
consecin, la prima trecere prin ciclul ct timp variabila i va avea valoarea egal cu p, iar j
nu va atinge valoarea p. Deci, prin interschimbarea a dou elemente ntre ele, elementul A[p]
ajunge n al doilea subir. Cnd procedura Partiie se termin, fiecare dintre cele rang(x) 1
elemente, care se afl n primul subir, vor fi mai mici sau egale cu x. Deci, cnd rang(x) 2,
probabilitatea ca n primul subir s fie i elemente (pentru orice i = 1, 2, . . . , n 1) este egal
cu 1/n.
Combinnd cele dou cazuri, putem trage concluzia c dimensiunea qp+1, a primului subir,
este egal cu 1, cu probabilitatea 2/n, iar aceast dimensiune este egal cu i (i = 2, 3, . . . , n 1),
cu probabilitatea 1/n.

O relaie de recuren pentru cazul mediu


Vom da n continuare o formul de recuren pentru timpul mediu de execuie al algoritmului
Quicksort-Aleator. Fie T (n) timpul mediu necesar ordonrii unui vector avnd n elemente.
Un vector de 1 element poate fi ordonat cu procedura Quicksort-Aleator n timp constant,
deci T (1) = (1). Procedura Quicksort-Aleator partiioneaz vectorul A[1..n] de dimensiune
n n (n) uniti de timp. Procedura Partiie returneaz un indice q, iar Quicksort-Aleator
este apelat recursiv pentru un vector de q elemente i pentru unul cu n q elemente. Deci timpul
mediu pentru ordonarea unui vector, avnd n elemente, se poate exprima astfel:
n1
!
1 X
T (n) = T (1) + T (n 1) + (T (q) + T (n q)) + (n). (8.2)
n q=1

Distribuia valorii q este aproape uniform, exceptnd cazul q = 1 care este de dou ori mai
probabil dect celelalte valori, cum am vzut anterior. Folosind valorile T (1) = (n) i T (n1) =
O(n2 ) (din analiza celui mai defavorabil caz), se poate scrie:
1 1
(T (1) + T (n 1)) = ((1) + O(n2 )) = O(n),
n n
i astfel termenul (n), n formula (8.2), poate absorbi expresia n1 (T (1) + T (n 1)). Astfel,
formula de recuren (8.2) poate fi scris sub forma:
n1
1X
T (n) = (T (q) + T (n q)) + (n). (8.3)
n q=1
Se poate observa c, pentru k = 1, 2, . . . , n 1, fiecare termen T (k) al sumei apare de dou
ori, o dat ca T (q), iar alt dat ca T (n q). Reducnd aceti termeni, formula final va fi:
n1
2X
T (n) = T (k) + (n). (8.4)
n
k=1
142 Capitolul 8 Sortarea rapid

Rezolvarea ecuaiei de recuren


Vom putea rezolva ecuaia de recuren (8.4) folosind metoda substituiei. S presupunem
c T (n) an lg n + b, pentru un a > 0 i b > 0. Valorile a i b pot fi alese destul de mari, astfel
nct an lg n + b s fie mai mare dect T (1). Pentru n > 1 avem:
n1 n1
2X 2X
T (n) = T (k) + (n) (ak lg k + b) + (n) =
n n
k=1 k=1
n1
X
2a 2b
= k lg k + (n 1) + (n).
n n
k=1

Vom arta, mai trziu, c ultima sum poate fi majorat astfel:


n1
X 1 2 1
k lg k n lg n n2 . (8.5)
2 8
k=1

Folosind aceast majorare, se obine:



2a 1 2 1 2 2b
T (n) n lg n n + (n 1) + (n)
n 2 8 n
a a
an lg n n + 2b + (n) = an lg n + b + (n) + b n an lg n + b,
4 4
a
deoarece valoarea lui a poate fi aleas astfel nct n s domine expresia (n) + b. Se poate deci
4
trage concluzia c timpul mediu de execuie a algoritmului de sortare rapid este O(n lg n).

Margini strnse pentru nsumarea cu chei


Pn1
Trebuie s mai demonstrm marginea (8.5) a sumei k=1 k lg k.
Deoarece fiecare termen al sumei este cel mult n lg n, se poate scrie:
n1
X
k lg k n2 lg n,
k=1

formul care reprezint o estimare destul de precis, abstracie fcnd de o constant, dar nu
este suficient de puternic pentru a obine T (n) = O(n lg n) ca soluie a recurenei. Pentru a
obine soluia de mai sus, avem nevoie de o margine de forma 21 n2 lg n (n2 ).
Aceast margine se poate obine folosind metoda de mprire a sumei n dou, ca n seciunea
3.2. Vom obine:
n1 dn/2e1 n1
X X X
k lg k = k lg k + k lg k.
k=1 k=1 k=dn/2e

Termenul lg k din prima sum a membrului drept se poate majora prin lg(n/2) = lg n 1, iar
termenul lg k din cea de a doua sum prin lg n. Astfel se obine
n1 dn/2e1 n1 n1 dn/2e1
X X X X X
k lg k (lg n 1) k + lg n k = lg n k k
k=1 k=1 k=dn/2e k=1 k=1
Probleme 143

1 1 n n 1 1
n(n 1) lg n 1 n2 lg n n2
2 2 2 2 2 8
dac n 2. Deci am obinut chiar formula (8.5).

Exerciii
8.4-1 Demonstrai c timpul de execuie al algoritmului de sortare rapid, n cazul cel mai
favorabil este (n lg n).

8.4-2 Demonstrai c expresia q 2 + (n q)2 , unde q = 1, 2, . . . , n 1, atinge maximul pentru


q = 1 sau q = n 1.

8.4-3 Demonstrai c timpul mediu de execuie al lui Quicksort-Aleator este (n lg n).

8.4-4 n practic, timpul de execuie al algoritmului de sortare rapid se poate mbunti con-
siderabil, innd cont de execuia mai rapid a algoritmului de sortare prin inserie pentru date
de intrare aproape ordonate. Cnd algoritmul de sortare rapid este apelat pentru un subir
avnd mai puin de k elemente, impunem ca acesta s returneze vectorul fr a-l sorta. Dup
revenirea din apelul iniial, s se execute algoritmul de sortare prin inserie pentru ntregul vector
(care este aproape ordonat). Argumentai afirmaia c acest algoritm de sortare are un timp
mediu de execuie O(nk + n lg(n/k)). Cum trebuie aleas valoarea lui k, teoretic i practic?

8.4-5 ? Demonstrai urmtoarea identitate:


Z
1 1
x ln xdx = x2 ln x x2 ,
2 4
i, folosind metoda
Pn1 de calculul aproximativ al integralei, dai o margine mai bun dect cea din
(8.5) pentru k=1 k lg k.

8.4-6 ? Modificai procedura Partiie, alegnd aleator trei elemente din vectorul A, iar dintre
acestea elementul de mijloc ca valoare pivot. Aproximai probabilitatea ca, n cazul cel mai
defavorabil, s se obin o partiionare n proporie de la (1 ), unde 0 < < 1.

Probleme
8-1 Corectitudinea partiiei
Argumentai afirmaia c procedura Partiie din seciunea 8.1 este corect. Demonstrai ur-
mtoarele:
a. Indicii i i j nu se refer niciodat la elemente ale lui A din afara intervalului [p..r].
b. La terminarea procedurii Partiie, indicele j nu va fi niciodat egal cu r (astfel,
partiionarea nu este niciodat trivial).
c. La terminarea partiionrii fiecare element din A[p..j] este mai mic sau egal cu orice element
din A[j + 1..r].
144 Capitolul 8 Sortarea rapid

8-2 Algoritmul de partiionare a lui Lomuto


Considerm urmtoarea variant a procedurii Partiie, dat de N. Lomuto. Vectorul A[p..r] se
mparte n vectorii A[p..i] i A[i + 1..j] astfel nct fiecare element din primul vector este mai
mic sau egal cu x = A[r] i fiecare element din cel de al doilea vector este mai mare ca x.
Partiie-Lomuto(A, p, r)
1: x A[r]
2: i p 1
3: pentru j p, r execut
4: dac A[j] x atunci
5: ii+1
6: interschimb A[i] A[j]
7: dac i < r atunci
8: returneaz i
9: altfel
10: returneaz i 1

a. Argumentai c procedura Partiie-Lomuto este corect.


b. Cel mult, de cte ori poate fi mutat un element n procedura Partiie? Dar n procedura
Partiie-Lomuto?
c. Argumentai c timpul de execuie al procedurii Partiie-Lomuto, ca de altfel i al
procedurii Partiie, pe un subir de n elemente, este (n).
d. Cum afecteaz, nlocuirea procedurii Partiie cu procedura Partiie-Lomuto, timpul
de execuie al algoritmului de sortare rapid Quicksort cnd toate datele de intrare sunt
egale?
e. Definii o procedur Partiie-Lomuto-Aleatoare care interschimb elementul A[r] cu
un element ales aleator din vectorul A[p..r], apoi apeleaz procedura Partiie-Lomuto.
Demonstrai c probabilitatea ca procedura Partiie-Lomuto-Aleatoare s returneze
valoarea q, este aceeai cu probabilitatea ca procedura Partiie-Aleatoare s returneze
valoarea p + r q.

8-3 Sortare circular


Profesorii Howard, Fine i Howard au propus urmtorul algoritm elegant pentru sortare:
Sorteaz-Circular(A, i, j)
1: dac A[i] > A[j] atunci
2: interschimb A[i] A[j]
3: dac i + 1 j atunci
4: revenire
5: k b(j i + 1)/3c Trunchiere.
6: Sorteaz-Circular(A, i, j k) Primele dou-treimi.
7: Sorteaz-Circular(A, i + k, j) Ultimele dou-treimi.
8: Sorteaz-Circular(A, i, j k) Primele dou-treimi din nou.
Probleme 145

a. Demonstrai c Sorteaz-Circular(A, 1,lungime[A]) ordoneaz corect vectorul de in-


trare A[1..n], unde n = lungime[A].

b. Determinai o formul de recuren, pentru timpul de execuie al procedurii Sorteaz-


Circular, i o margine asimptotic tare (folosind notaia ), pentru timpul de execuie,
n cazul cel mai defavorabil.

c. Comparai timpul de execuie al algoritmului Sorteaz-Circular, n cazul cel mai de-


favorabil, cu timpii corespunztori ai algoritmilor de sortare prin inserare, sortare prin
interclasare, heapsort i sortare rapid. Merit profesorii s fie felicitai?

8-4 Adncimea stivei pentru algoritmul de sortare rapid


Algoritmul Quicksort, prezentat n seciunea 8.1, se autoapeleaz de dou ori. Dup apelul
procedurii Partiie, este sortat recursiv primul subir, apoi subirul al doilea. Al doilea apel
recursiv din Quicksort nu este neaprat necesar, el poate fi evitat prin folosirea unei structuri de
control iterative. Aceast tehnic, numit recursivitate de coad, este oferit n mod automat
de compilatoarele mai bune. Se consider urmtoarea variant a algoritmului de sortare rapid,
care simuleaz recursivitatea de coad:
Quicksort0 (A, p, r)
1: ct timp p < r execut
2: Partiionarea i sortarea primului subir
3: q Partiie(A, p, r)
4: Quicksort0 (A, p, q)
5: pq+1

a. Artai c algoritmul Quicksort0 (A, 1,lungime[A]) sorteaz corect vectorul A.


Compilatoarele, de obicei, execut apelurile recursive, folosind o stiv care conine infor-
maii pertinente, inclusiv valorile parametrilor la fiecare apel. Informaiile referitoare la cel
mai recent apel se gsesc n vrful stivei, pe cnd informaiile referitoare la primul apel
se pstreaz la baza stivei. Cnd se apeleaz o procedur, informaiile sale se depun n
vrful stivei (operaia push), iar la terminarea execuiei, aceste informaii se scot din stiv
(operaia pop). Deoarece presupunem c parametrii vectorului se reprezint cu ajutorul
pointerilor, informaiile necesare fiecrui apel necesit un spaiu de stiv de O(1) uniti.
Adncimea stivei este spaiul maxim utilizat de stiv, n timpul execuiei algoritmului.

b. Descriei un scenariu n care, pentru un vector de intrare de dimensiune n, adncimea


stivei algoritmului Quicksort0 este (n).

c. Modificai textul algoritmului Quicksort0 astfel nct adncimea stivei, n cazul cel mai
defavorabil, s fie (lg n). Pstrai valoarea O(n lg n) pentru timpul mediu de execuie a
algoritmului.

8-5 Partiionare mijlocul-din-3


O metod prin care procedura Quicksort-Aleator poate fi mbuntit este de a face
partiionarea n jurul unui element x, ales mai atent dect aleator. O metod obinuit poate fi
metoda mijlocul-din-3 , care const n a alege elementul mijlociu ca mrime, dintre trei elemente
146 Capitolul 8 Sortarea rapid

alese la ntmplare din vector. S considerm, pentru problema de fa, c toate elementele
vectorului de intrare A[1..n] sunt distincte i c n 3. S notm cu A0 [1..n] vectorul sortat
rezultat. Fie pi = Pr{x = A0 [i]} probabilitatea ca elementul pivot x, ales cu metoda mijlocul-
din-3, s fie al i-lea element n vectorul de ieire.
a. Dai o formul exact pentru pi n funcie de n i i, pentru i = 2, 3, . . . , n 1. (S observm
c p1 = pn = 0.)
b. Cu ct crete probabilitatea alegerii ca pivot a elementului x = A0 [b(n + 1)/2c], mijlocul
vectorului A[1..n] fa de implementarea original? Calculai limita acestei probabiliti
cnd n .
c. Dac numim partiionare bun acea partiionare care folosete ca pivot elementul x =
A0 [i], unde n/3 i 2n/3, atunci cu ct crete probabilitatea obinerii unei mpriri
bune fa de implementarea original? (Indicaie: Aproximai suma cu o integral.)

d. Artai c metoda mijlocul-din-3 afecteaz numai factorul constant din expresia (n lg n)


a timpului de execuie al algoritmului de sortare rapid.

Note bibliografice
Algoritmul de sortare rapid a fost inventat de Hoare [98]. Sedgewick [174] ofer o prezentare
bun a detaliilor de implementare a acestui algoritm. Avantajele algoritmilor aleatori au fost
tratate de Rabin [165].
9 Sortare n timp liniar

n capitolele precedente au fost prezentai civa algoritmi de complexitate O(n lg n). Aceast
margine superioar este atins de algoritmii de sortare prin interclasare i heapsort n cazul cel
mai defavorabil; respectiv pentru quicksort corespunde n medie. Mai mult dect att, pentru
fiecare din aceti algoritmi putem efectiv obine cte o secven de n numere de intrare care
determin execuia algoritmului n timpul (n lg n).
Aceti algoritmi au o proprietate interesant: ordinea dorit este determinat n exclusivitate
pe baza comparaiilor ntre elementele de intrare. Astfel de algoritmi de sortare se numesc sortri
prin comparaii. Toi algoritmii de sortare prezentai pn acum sunt de acest tip.
n seciunea 9.1 vom demonstra c oricare sortare prin comparaii trebuie s fac, n cel mai
defavorabil caz, (n lg n) comparaii pentru a sorta o secven de n elemente. Astfel, algoritmul
de sortare prin interclasare i heapsort sunt asimptotic optimale i nu exist nici o sortare prin
comparaii care s fie mai rapid dect cu un factor constant.
Seciunile 9.2, 9.3 i 9.4 studiaz trei algoritmi de sortare sortare prin numrare, ordonare
pe baza cifrelor i ordonare pe grupe care se execut n timp liniar. Se subnelege c aceti
algoritmi folosesc, pentru a determina ordinea de sortare, alte operaii dect comparaiile. n
consecin, lor nu li se aplic marginea inferioar (n lg n).

9.1. Margini inferioare pentru sortare


ntr-o sortare prin comparaii folosim numai comparaiile dintre elemente pentru a ctiga
informaii de ordine despre o secven de intrare ha1 , a2 , ..., an i. Respectiv, date fiind elementele
ai i aj , facem testele ai < aj , ai aj , ai = aj , ai aj , sau ai > aj pentru a determina ordinea
lor relativ. Nu putem s inspectm valorile elementelor sau s obinem informaii asupra ordinii
lor n nici un alt mod.
n aceast seciune vom presupune, fr a pierde din generalitate, c toate elementele de
intrare sunt distincte. Dat fiind aceast presupunere, comparaiile de tipul ai = aj sunt nefolo-
sitoare, deci putem s afirmm c nu sunt fcute comparaii de acest fel. Studiind comparaiile
ai aj , ai aj , ai > aj i ai < aj observm c acestea sunt echivalente, deoarece aduc
informaie identic despre ordinea relativ a lui ai i aj . De aceea vom considera c toate com-
paraiile au forma ai aj .

Modelul arborelui de decizie


Sortrile prin comparaii pot fi viziualizate n mod abstract n termenii arborilor de decizie.
Un arbore de decizie reprezint comparaiile realizate de un algoritm de sortare cnd acesta
opereaz asupra unor date de intrare avnd o mrime dat. Controlul, micarea datelor i toate
celelalte aspecte ale algoritmului sunt ignorate. Figura 9.1 vizualizeaz un arbore de decizie
corespunztor algoritmului de sortare prin inserie din seciunea 1.1 ce opereaz cu o secven
de intrare avnd trei elemente.
148 Capitolul 9 Sortare n timp liniar

Figura 9.1 Arborele de decizie corespunztor sortrii prin inserie care opereaz cu trei elemente. Sunt
posibile 3! = 6 permutri ntre elementele de intrare, deci arborele de decizie trebuie s aib cel puin 6
frunze.

ntr-un arbore de decizie fiecare nod intern este etichetat prin ai : aj pentru i i j din
intervalul 1 i, j n, unde n este numrul de elemente din secvena de intrare. Fiecare
frunz este etichetat cu o permutare h(1), (2), ..., (n)i. (Vezi seciunea 6.1 pentru noiuni
de baz asupra permutrilor.) Execuia algoritmului de sortare corespunde trasrii unui drum
de la rdcina arborelui de decizie la o frunz. La fiecare nod intern este fcut o comparaie
ai aj . Subarborele stng dicteaz comparaiile urmtoare pentru ai aj , iar subarborele
drept dicteaz comparaiile urmtoare pentru ai > aj . Cnd ajungem la o frunz, algoritmul
de sortare a stabilit ordonarea a(1) a(2) . . . a(n) . Pentru ca algoritmul de sortare s
ordoneze adecvat, fiecare dintre cele n! permutri de n elemente trebuie s apar n dreptul unei
frunze a arborelui de decizie.

O margine inferioar n cel mai defavorabil caz


Lungimea celui mai lung drum de la rdcina unui arbore de decizie la oricare dintre frunzele
sale reprezint numrul de comparaii, n cel mai defavorabil caz, pe care le realizeaz algoritmul
de sortare. n consecin, numrul de comparaii, n cel mai defavorabil caz, pentru o sortare prin
comparaii corespunde nlimii arborelui de decizie. O margine inferioar a nlimilor arborilor
de decizie este astfel o margine inferioar a timpului de execuie al oricrui algoritm de sortare
prin comparaii. Urmtoarea teorem stabilete o astfel de margine inferioar.

Teorema 9.1 Orice arbore de decizie care sorteaz n elemente are nlimea (n lg n).

Demonstraie. S considerm un arbore de decizie avnd nlimea h i care sorteaz n ele-


mente. ntruct exist n! permutri ale celor n elemente, fiecare permutare reprezentnd o ordine
distinct de sortare, arborele trebuie s aib cel puin n! frunze. Deoarece un arbore binar avnd
nlimea h nu are mai mult de 2h frunze, avem
n! 2h ,
iar, prin logaritmare, rezult
h lg(n!),
deoarece funcia lg este monoton cresctoare. Din aproximarea lui Stirling (2.11), avem
n n
n! > ,
e
9.2. Sortarea prin numrare 149

unde e = 2.71828... este baza logaritmilor naturali; astfel


n n
h lg = n lg n n lg e = (n lg n).
e

Corolarul 9.2 Metoda heapsort i metoda de sortare prin interclasare sunt metode de sortare
prin comparaii asimptotic optimale.
Demonstraie. n cazul metodelor de sortare heapsort i sortarea prin interclasare, marginile
superioare O(n lg n) asupra duratei timpilor de execuie corespund marginii inferioare (n lg n)
stabilite de teorema 9.1 pentru cazul cel mai defavorabil.

Exerciii
9.1-1 Care este cea mai mic adncime posibil a unei frunze ntr-un arbore de decizie pentru
un algoritm de sortare?
9.1-2 Obinei margini asimptotic P
strnse la lg(n!) fr a folosi aproximaia Stirling. n loc de
n
aceast aproximaie, evaluai suma k=1 lg k folosind tehnicile prezentate n cadrul seciunii 3.2.
9.1-3 Artai c nu exist nici o sortare prin comparaii avnd timpul de execuie liniar pentru
cel puin jumtate din cele n! intrri de lungime n. Ce se poate spune n cazul unei fraciuni 1/n
din datele de intrare de lungime n? Dar despre o fraciune 1/2n ?
9.1-4 Profesorul Solomon afirm c marginea inferioar (n lg n) pentru sortarea a n numere nu
se aplic n cazul mediului de care dispune, unde dup o singur comparaie ai : aj , programul se
ramific n trei direcii, dup cum ai < aj , ai = aj respectiv ai > aj . Demonstrai c profesorul
nu are dreptate demonstrnd c numrul comparaiilor tridirecionale cerut de sortarea celor n
elemente este tot (n lg n).
9.1-5 Demonstrai c, pentru a interclasa dou liste ordonate ce conin fiecare cte n elemente,
sunt necesare 2n 1 comparaii n cazul cel mai defavorabil.
9.1-6 Se consider o secven de n elemente care trebuie sortate. Datele de intrare sunt formate
din n/k subsecvene, fiecare coninnd k elemente. Toate elementele dintr-o subsecven dat
sunt mai mici dect elementele din subsecvena urmtoare i mai mari dect elementele din
subsecvena precedent. Astfel, pentru sortarea ntregii secvene de lungime n este suficient
sortarea celor k elemente din fiecare dintre cele n/k subsecvene. Gsii o margine inferioar
(n lg k) a numrului de comparaii necesar pentru rezolvarea acestei variante a problemei de
sortare. (Indicaie: combinarea simpl a marginilor inferioare pentru subecvenele individuale nu
este riguroas.)

9.2. Sortarea prin numrare


Sortarea prin numrare presupune c fiecare dintre cele n elemente ale datelor de intrare
este un numr ntreg ntre 1 i k, pentru un numr ntreg k oarecare. Cnd k = O(n), sortarea
se execut n timpul O(n).
150 Capitolul 9 Sortare n timp liniar

Figura 9.2 Modul de funcionare al algoritmului Sortare-Prin-Numrare pe un tablou A [1..8] de


intrare, unde fiecare element din tabloul A este un numr ntreg pozitiv nu mai mare dect k = 6. (a)
Tabloul A i tabloul auxiliar C dup liniei 4. (b) Tabloul C dup executarea liniei 7. (c)-(e) Tabloul
de ieire B i tabloul auxiliar C dup unul, dou, respectiv trei iteraii ale buclei din liniile 911. Doar
elementele haurate din tabloul B au fost completate. (f ) Tabloul B sortat, furnizat la ieire.

Ideea de baz n sortarea prin numrare este de a determina numrul de elemente mai mici
dect x, pentru fiecare element x din datele de intrare. Acest informaie poate fi utilizat pentru
a poziiona elementul x direct pe poziia sa din tabloul de ieire. De exemplu, dac exist 17
elemente mai mici dect x, atunci x va fi pe poziia 18 n tabloul de ieire. Aceast schem trebuie
uor modificat n situaia n care exist mai multe elemente avnd aceeai valoare, ntruct nu
dorim s le aezm pe toate n aceeai poziie.
n algoritmul pentru sortarea prin numrare presupunem c datele de intrare formeaz un
tablou A[1..n], i deci lungime [A] = n. Sunt necesare alte dou tablouri suplimentare, tabloul
B [1..n], care cuprinde datele de ieire sortate, i tabloul C [1..k], pentru stocarea temporar n
timpul lucrului.
Sortare-Prin-Numrare(A, B, k)
1: pentru i 1, k execut
2: C [i] 0
3: pentru j 1, lungime [A] execut
4: C [A [j]] C [A [j]] + 1
5: . C[i] conine acum numrul elementelor egale cu i.
6: pentru i 2, k execut
7: C [i] C [i] + C [i 1]
8: . C[i] conine numrul elementelor mai mici sau egale cu i.
9: pentru j lungime [A] , 1, 1 execut
10: B [C [A [j]]] A [j]
11: C [A [j]] C [A [j]] 1

Algoritmul de sortare prin numrare este ilustrat n figura 9.2. Dup iniializarea din liniile
9.2. Sortarea prin numrare 151

12, n liniile 34 se contorizeaz fiecare element de intrare. Dac valoarea unui element de
intrare este i, se incrementeaz valoarea lui C [i]. Astfel, dup liniile 34, C [i] pstreaz un
numr de elemente de intrare egal cu i pentru fiecare numr ntreg i = 1, 2, . . . , k. n liniile 67
se determin, pentru fiecare i = 1, 2, . . . , k, numrul elementelor de intrare mai mici sau egale
dect i; aceasta se realizeaz prin pstrarea n C[k] a sumei primelor k elemente din tabloul
iniial.
n final, n liniile 911, fiecare element A[j] se plaseaz pe poziia sa corect determinat din
tabloul de ieire B, astfel nct acesta este ordonat. Dac toate cele n elemente sunt distincte,
la prima execuie a liniei 9, pentru fiecare A[j], valoarea C[A[j]] este poziia final corect a lui
A [j] n tabloul de ieire, ntruct exist C [A [j]] elemente mai mici sau egale cu A [j]. Deoarece
elementele ar putea s nu fie distincte, decrementm valoarea C[A[j]] de fiecare dat cnd plasm
o valoare A[j] n tabloul B; aceasta face ca urmtorul element de intrare cu o valoare egal cu
A [j], dac exist vreunul, s mearg n poziia imediat dinaintea lui A [j] n tabloul de ieire.
Ct timp necesit sortarea prin numrare? Bucla pentru din liniile 12 necesit timpul O(k),
bucla pentru din liniile 34 necesit timpul O(n), bucla pentru din liniile 67 necesit timpul
O(k), iar bucla pentru din liniile 911 necesit timpul O(n). Deci timpul total este O(k + n).
n practic se utilizeaz sortarea prin numrare cnd avem k = O(n), caz n care timpul necesar
este O(n).
Sortarea prin numrare are un timp mai bun dect marginea inferioar egal cu (n lg n)
demonstrat n seciunea 9.1, deoarece nu este o sortare prin comparaii. De fapt, n cod nu
apar comparaii ntre elementele de intrare. n schimb, sortarea prin numrare folosete valorile
elementului ca indice ntr-un tablou. Marginea inferioar (n lg n) nu se aplic atunci cnd ne
ndeprtm de modelul sortrii prin comparaii.
O proprietate important a sortrii prin numrare este stabilitatea: numerele cu aceeai
valoare apar n tabloul de ieire n aceeai ordine n care se gsesc n tabloul de intrare. Adic,
legturile dintre dou numere sunt distruse de regula conform creia oricare numr care apare
primul n vectorul de intrare, va aprea primul i n vectorul de ieire. Desigur, stabilitatea
este important numai cnd datele nvecinate sunt deplasate mpreun cu elementul n curs de
sortare. Vom vedea n seciunea urmtoare de ce stabilitatea este important.

Exerciii
9.2-1 Folosind figura 9.2 ca model, ilustrai modul de operare al algoritmului Sortare-Prin-
Numrare pe tabloul A = h7, 1, 3, 1, 2, 4, 5, 7, 2, 4, 3i.
9.2-2 Demonstrai c Sortare-Prin-Numrare este stabil.
9.2-3 Se presupune c bucla pentru din linia 9 a procedurii Sortare-Prin-Numrare este
rescris sub forma:
pentru j 1, lungime [A] execut
Artai c algoritmul modificat astfel funcioneaz corect. Algoritmul modificat este stabil?
9.2-4 Se presupune c ieirea algoritmului de sortare este un flux de date, de exemplu, o afiare
n mod grafic. Modificai algoritmul Sortare-Prin-Numrare pentru a obine rezultatul n
ordinea sortat fr a utiliza vectori suplimentari n afara lui A i C. (Indicaie: legai elementele
tabloului A avnd aceleai chei n liste. Unde exist un spaiu liber pentru pstrarea pointerilor
listei nlnuite?)
152 Capitolul 9 Sortare n timp liniar

9.2-5 Date fiind n numere ntregi din intervalul [1,k], preprocesai datele de intrare i apoi
rspundei ntr-un timp O(1) la orice interogare privind numrul total de valori ntregi dintre
cele n, care se situeaz n intervalul [a..b]. Algoritmul propus ar trebui s foloseasc un timp de
preprocesare O(n + k).

9.3. Ordonare pe baza cifrelor


Ordonarea pe baza cifrelor este algoritmul folosit de ctre mainile de sortare a cartelelor,
care se mai gsesc la ora actual numai n muzeele de calculatoare. Cartelele sunt organizate n
80 de coloane, i fiecare coloan poate fi perforat n 12 poziii. Sortatorul poate fi programat
mecanic s examineze o coloan dat a fiecrei cartele dintr-un pachet i s distribuie fiecare
cartela ntr-una dintre cele 12 cutii, n funcie de poziia perforat. Un operator poate apoi
s strng cartelele cutie cu cutie, astfel nct cartelele care au prima poziie perforat s fie
deasupra cartelelor care au a doua poziie perforat .a.m.d.
Pentru cifre zecimale sunt folosite numai 10 poziii n fiecare coloan. (Celelalte dou poziii
sunt folosite pentru codificarea caracterelor nenumerice). Un numr avnd d cifre ar ocupa un
cmp format din d coloane. ntruct sortatorul de cartele poate analiza numai o singur coloan
la un moment dat, problema sortrii a n cartele n funcie de un numr avnd d cifre necesit
un algoritm de sortare.
Intuitiv, am putea dori s sortm numere n funcie de cea mai semnificativ cifr, s sortm
recursiv fiecare dintre cutiile ce se obin, i apoi s combinm pachetele n ordine. Din nefericire,
ntruct cartelele din 9 dintre cele 10 cutii trebuie s fie pastrate pentru a putea sorta fiecare
dintre cutii, aceast procedur genereaz teancuri intermediare de cartele care trebuie urmrite.
(Vezi exerciiul 9.3-5.)
Ordonarea pe baza cifrelor rezolv problema sortrii cartelelor ntr-un mod care contrazice
intuiia, sortnd nti n funcie de cea mai puin semnificativ cifr. Cartelele sunt apoi
combinate ntr-un singur pachet, cele din cutia 0 precednd cartelele din cutia 1, iar acestea
din urm precednd pe cele din cutia 2 i aa mai departe. Apoi ntregul pachet este sortat
din nou n funcie de a doua cifr cea mai puin semnificativ i recombinat apoi ntr-o manier
asemntoare. Procesul continu pn cnd cartelele au fost sortate pe baza tuturor celor d cifre.
De remarcat c n acel moment cartelele sunt complet sortate n funcie de numrul avnd d
cifre. Astfel, pentru sortare sunt necesare numai d treceri prin lista de numere. n figura 9.3 este
ilustrat modul de operare al algoritmului de ordonare pe baza cifrelor pe un pachet de apte
numere de cte trei cifre.
Este esenial ca sortarea cifrelor n acest algoritm s fie stabil. Sortarea realizat de ctre
un sortator de cartele este stabil, dar operatorul trebuie s fie atent s nu schimbe ordinea
cartelelelor pe msur ce acestea ies dintr-o cutie, chiar dac toate cartelele dintr-o cutie au
aceeai cifr n coloana aleas.
ntr-un calculator care funcioneaz pe baz de acces secvenial aleator, ordonarea pe baza
cifrelor este uneori utilizat pentru a sorta nregistrrile de informaii care sunt indexate cu chei
avnd cmpuri multiple. De exemplu, am putea dori s sortm date n funcie de trei parametri:
an, lun, zi. Am putea executa un algoritm de sortare cu o funcie de comparare care, considernd
dou date calendaristice, compar anii, i dac exist o legtur, compar lunile, iar dac apare
din nou o legtur, compar zilele. Alternativ, am putea sorta informaia de trei ori cu o sortare
9.3. Ordonare pe baza cifrelor 153

Figura 9.3 Modul de funcionare al algoritmului de ordonare pe baza cifrelor pe o list de apte nu-
mere a cte 3 cifre. Prima coloan este intrarea. Celelalte coloane prezint lista dup sortri succesive n
funcie de poziiile cifrelor n ordinea cresctoare a semnificaiei. Sgeile verticale indic poziia cifrei
dup care s-a sortat pentru a produce fiecare list din cea precedent.

stabil: prima dup zi, urmtoarea dup lun, i ultima dup an.
Pseudocodul pentru algoritmul de ordonare pe baza cifrelor este evident. Urmtoarea pro-
cedur presupune c ntr-un tablou A avnd n elemente, fiecare element are d cifre; cifra 1 este
cifra cu ordinul cel mai mic, iar cifra d este cifra cu ordinul cel mai mare.
Ordonare-Pe-Baza-Cifrelor(A, d)
1: pentru i 1, d execut
2: folosete o sortare stabil pentru a sorta tabloul A dup cifra i

Corectitudinea algoritmului de ordonare pe baza cifrelor poate fi demonstrat prin inducie


dup coloanele care sunt sortate (vezi exerciiul 9.3-3). Analiza timpului de execuie depinde de
sortarea stabil folosit ca algoritm intermediar de sortare. Cnd fiecare cifr este n intervalul
[1, k], iar k nu este prea mare, sortarea prin numrare este opiunea evident. Fiecare trecere
printr-o mulime de n numere a cte d cifre se face n timpul (n + k). Se fac d treceri, astfel
nct timpul total necesar pentru algoritmul de ordonare pe baza cifrelor este (dn + kd). Cnd
d este constant i k = O(n), algoritmul de ordonare pe baza cifrelor se execut n timp liniar.
Unii informaticieni consider c numrul biilor ntr-un cuvnt calculator este (lg n). Pentru
exemplificare, s presupunem c d lg n este numrul de bii, unde d este o constant pozitiv.
Atunci, dac fiecare numr care va fi sortat ncape ntr-un cuvnt al calculatorului, l vom putea
trata ca pe un numr avnd d cifre reprezentat n baza n. De exemplu, s considerm sortarea a
1 milion de numere avnd 64 de bii. Tratnd aceste numere ca numere de patru cifre n baza 216 ,
putem s le sortm pe baza cifrelor doar prin patru treceri, comparativ cu o sortare clasic prin
comparaii de timp (n lg n) care necesit aproximativ lg n = 20 de operaii pentru fiecare numr
sortat. Din pcate, versiunea algoritmului de ordonare pe baza cifrelor care folosete sortarea
prin numrare ca sortare intermediar stabil nu sorteaz pe loc, lucru care se ntmpl n cazul
multora din sortrile prin comparaii de timp (n lg n). Astfel, dac se dorete ca necesarul de
memorie s fie mic, atunci este preferabil algoritmul de sortare rapid.

Exerciii
9.3-1 Folosind figura 9.3 ca model, ilustrai modul de fucionare al algoritmului Ordonare-
Pe-Baza-Cifrelor pe urmtoarea list de cuvinte n limba englez: COW, DOG, SEA, RUG,
ROW, MOB, BOX, TAB, BAR, EAR, TAR, DIG, BIG, TEA, NOW, FOX.
154 Capitolul 9 Sortare n timp liniar

9.3-2 Care din urmtorii algoritmi de sortare sunt stabili: sortarea prin inserie, sortarea prin
interclasare, heapsort i sortarea rapid? Realizai o schem simpl care s fac stabil orice
algoritm de sortare. Ct timp i spaiu suplimentar necesit schema realizat?

9.3-3 Demonstrai prin inducie c algoritmul de ordonare pe baza cifrelor funcioneaz corect.
Unde avem nevoie n demonstraie de presupunerea c sortarea intermediar este stabil?

9.3-4 Artai cum se sorteaz n ntregi din intervalul [1, n2 ] n timp O(n).

9.3-5 ? Determinai numrul exact de treceri necesare pentru a sorta numere zecimale avnd
d cifre, n cel mai defavorabil caz, pentru primul algoritm din acest capitol pentru ordonarea
cartelelor. De cte teancuri de cartele ar avea nevoie un operator pentru a urmri aceast sortare?

9.4. Ordonarea pe grupe


Ordonarea pe grupe se execut, n medie, n timp liniar. Ca i sortarea prin numrare,
Ordonarea pe grupe este rapid pentru c face anumite presupuneri despre datele de intrare.
n timp ce sortarea prin numrare presupune c intrarea const din ntregi dintr-un domeniu
mic, ordonarea pe grupe presupune c intrarea este generat de un proces aleator care distribuie
elementele n mod uniform n intervalul [0, 1). (Vezi seciunea 6.2 pentru definiia distribuiei
uniforme.)
Principiul algoritmului de ordonare pe grupe este de a mpri intervalul [0, 1) n n
subintervale egale, numite grupe (engl. buckets) i apoi s distribuie cele n numere de intrare n
aceste grupe. ntruct datele de intrare sunt uniform distribuite n intervalul [0, 1), nu ne atep-
tm s fie prea multe numere n fiecare grup. Pentru a obine rezultatul dorit, sortm numerele
din fiecare grup, apoi trecem prin fiecare grup n ordine, listnd elementele din fiecare.
Pseudocodul nostru pentru ordonarea pe grupe presupune c datele de intrare formeaz un
tablou A avnd n elemente i c fiecare element A[i] satisface relaia 0 A[i] < 1. Codul necesit
un tablou auxiliar B[0..n 1] de liste nlnuite (reprezentnd grupele) i presupune c exist un
mecanism pentru meninerea acestor liste. (n seciunea 11.2 se descrie cum se implementeaz
operaiile de baz pe listele nlnuite.)
Ordonare-Pe-Grupe(A)
1: n lungime[A]
2: pentru i 1, n execut
3: insereaz A[i] n lista B [bnA [i]c]
4: pentru i 0, n 1 execut
5: sorteaz lista B[i] folosind sortarea prin inserie
6: concateneaz n ordine listele B [0] , B [1] , ..., B [n 1]

Figura 9.4 ilustreaz modul de funcionare al algoritmului de ordonare pe grupe pe un tablou


de intrare cu 10 numere.
Pentru a demonstra c acest algoritm funcioneaz corect, se consider dou elemente A [i] i
A [j]. Dac aceste elemente sunt distribuie n aceeai grup, ele apar n ordinea relativ adecvat
n secvena de ieire, deoarece grupa lor este sortat de sortarea prin inserie. S presupunem,
totui, c ele sunt distribuite n grupe diferite. Fie aceste grupe B[i0 ] i respectiv B[j 0 ], i s
9.4. Ordonarea pe grupe 155

Figura 9.4 Funcionarea algoritmului Ordonare-Pe-Grupe. (a) Tabloul de intrare A[1..10]. (b)
Tabloul B[0..9] al listelor (reprezentnd grupele) sortate dup linia a cincea a algoritmului. Grupa i
cuprinde valorile din intervalul [i/10, (i + 1)/10). Ieirea sortat const dintr-o concatenare n ordine a
listelor B [0], B [1] , ..., B [9].

presupunem, fr a pierde din generalitate, c i0 < j 0 . Cnd listele lui B sunt concatenate n
linia 6, elementele grupei B[i0 ] apar naintea elementelor lui B [j 0 ], i astfel A [i] precede A [j] n
secvena de ieire. Deci trebuie s artm c A [i] A [j]. Presupunnd contrariul, avem

i0 = bnA[i]c bnA[j]c = j 0 ,

ceea ce este o contradicie, ntruct i0 < j 0 . Aadar, ordonarea pe grupe funcioneaz corect.
Pentru a analiza timpul de execuie, s observm mai nti c toate liniile, cu excepia liniei
5, necesit, n cel mai defavorabil caz, timpul O(n). Timpul total pentru a examina n linia 5
toate grupele este O(n) i, astfel, singura parte interesant a analizei este timpul consumat de
sortrile prin inserie din linia 5.
Pentru a analiza costul sortrilor prin inserie, fie ni o variabil aleatoare desemnnd numrul
de elemente din grupa B[i]. ntruct sortarea prin inserie se execut n timp ptratic
(vezi

seciunea 1.2), timpul necesar sortrii elementelor n grupele B [i] este E O n2i = O E n2i .
n consecin, timpul mediu total necesar sortrii tuturor elementelor n toate grupele va fi
n1
n1 !
X X
2 2
O E ni = O E ni . (9.1)
i=0 i=0

Pentru a evalua aceast sum trebuie s determinm distribuia pentru fiecare variabil
aleatoare ni . Avem n elemente n n grupe. Probabilitatea ca un element dat s intre ntr-o grup
B [i] este 1/n, ntruct fiecare grup este responsabil pentru 1/n elemente din intervalul [0, 1).
Astfel, situaia este asemntoare cu exemplul aruncatului mingii din seciunea (6.6.2): avem n
mingi (elemente) i n cutii (reprezentnd grupele), i fiecare minge este aruncat independent, cu
probabilitatea p = 1/n de a intra ntr-o anume grup. Astfel, probabilitatea ca ni = k urmeaz o
distribuie binomial b(k; n, p) care are media E [ni ] = np = 1 i varianta V ar [ni ] = np(1 p) =
156 Capitolul 9 Sortare n timp liniar

1 1/n. Pentru fiecare variabil aleatoare X, ecuaia (6.30) este echivalent cu


1 1
E n2i = V ar [ni ] + E 2 [ni ] = 1 + 12 = 2 = (1) .
n n
Utiliznd acest salt n ecuaia (9.1) concluzionm c timpul mediu pentru sortarea prin inserie
este O(n). Astfel, ntregul algoritm de ordonare pe grupe se execut n timp mediu liniar.

9.4.1. Exerciii
9.4-1 Utiliznd ca model figura 9.4, ilustrai modul de funcionare al algoritmului Ordonare-
Pe-Grupe pe tabloul A = h.79, .13, .16, .64, .39, .20, .89, .53, .71, .42i.
9.4-2 Care este timpul de execuie n cazul cel mai defavorabil pentru algoritmul de ordonare
pe grupe? Ce modificare simpl a algoritmului pstreaz timpul mediu liniar de execuie i face
ca timpul de execuie n cazul cel mai defavorabil s fie O(n lg n)?
9.4-3 ? Se dau n puncte n cercul unitate, pi = (xi , yi ), astfel nct 0 < x2i + yi2 1 pentru
i = 1, 2, ..., n. Presupunei c punctele sunt uniform distribuite, adic probabilitatea de a gsi
un punct n orice regiune a cercului este proporional cu aria acelei regiuni. Scriei un algoritm
n timpul
p mediu (n) care s sorteze cele n puncte n funcie de distanele fa de origine
di = x2i + yi2 . (Indicaie: proiectai dimensiunile grupelor din Ordonarea-Pe-Grupe pentru
a reflecta distribuia uniform a punctelor n cercul unitate.)
9.4-4 ? O funcie de distribuie a probabilitii P (x) pentru variabila aleatoare X este
definit de P (x) = Pr{X x}. Considerai o list de n numere cu o funcie de distribuie de
probabilitate continu P care este calculabil n timpul O(1). Artai cum se sorteaz numerele
n timp mediu liniar.

Probleme
9-1 Marginile inferioare n cazul mediu la sortarea prin comparaii
n aceast problem demonstrm o margine inferioar (n lg n) a timpului mediu de execuie
pentru orice sortare prin comparaii determinist sau aleatoare efectuat pe n date de intrare.
ncepem prin examinarea unei sortri prin comparaii deterministe A avnd arborele de decizie
TA . Presupunem c fiecare permutare a intrrilor lui A apare cu o probabilitate constant.
a. S presupunem c fiecare frunz a lui TA este etichetat cu probabilitatea de a fi atins
n cazul unor date de intrare aleatoare. Demonstrai c exact n! frunze sunt etichetate cu
1/n! i c restul sunt etichetate cu 0.
b. Fie D(T ) lungimea drumului extern a arborelui T ; adic, D(T ) este suma adncimilor
tuturor frunzelor lui T . Fie T un arbore avnd k > 1 frunze, i fie LT i RT subarborii
stng i drept ai lui T . Artai c D(T ) = D(LT ) + D(RT ) + k.
c. Fie d(k) valoarea minim a lui D(T ) pe toi arborii de decizie T avnd k > 1 frunze.
Artai c d(k) = min1ik1 {d(i) + d(k i) + k}. (Indicaie: Considerai un arbore T
avnd k frunze care atinge minimul. Fie i numrul de frunze din LT i k i numrul de
frunze din RT .)
Probleme 157

d. Demonstrai c pentru o valoare dat a lui k > 1 i i din domeniul 1 i k 1, funcia


i lg i + (k i) lg(k i) este minim pentru i = k/2. Artai c d(k) = (k lg k).
e. Demonstrai c D (TA ) = (n! lg (n!)) pentru TA , i concluzionai c timpul mediu pentru
sortarea a n elemente este (n lg n) .
Acum s considerm o sortare aleatoare prin comparaii B. Putem extinde modelul arborelui
de decizie pentru a gestiona caracterul aleator prin ncorporarea a dou feluri de noduri: noduri
de comparaie i noduri de randomizare. Un astfel de nod modeleaz o selectare aleatoare
de forma Aleator(1, r), fcut de ctre algoritmul B; nodul are r descendeni, fiecare dintre ei
avnd aceeai probabilitate de a fi selectat n timpul execuiei algoritmului.

f. Artai c, pentru orice sortare aleatoare prin comparaii B, exist o sortare determinist
prin comparaii A care nu face n medie mai multe comparaii dect B.

9-2 Sortarea pe loc n timp liniar

a. S presupunem c avem de sortat un tablou cu n articole i cheia fiecrui articol are valoarea
0 sau 1. Realizai un algoritm simplu, de timp liniar, care s sorteze pe loc cele n articole.
Pe lng memoria necesar reprezentrii tabloului, putei folosi un spaiu suplimentar de
memorie avnd dimensiune constant.
b. Poate sortarea realizat la punctul (a) s fie utilizat pentru o ordonare pe baza cifrelor
de timp O(bn) a n articole avnd chei de b-bii? Explicai cum sau de ce nu.
c. S presupunem c cele n nregistrri au chei n intervalul [1, k]. Artai cum se poate
modifica sortarea prin numrare astfel nct nregistrrile s poat fi sortate pe loc n
timpul O(n + k). Putei folosi un spaiu suplimentar de memorie de ordinul O(k), pe lng
tabloul de intrare. (Indicaie: Cum ai realiza acest lucru pentru k = 3?)

Note bibliografice
Modelul arborelui de decizie pentru studiul sortrilor prin comparaii a fost introdus de
ctre Ford i Johnson [72]. Tratatul cuprinztor al lui Knuth asupra sortrii [123] acoper multe
variaii pe problema sortrii, inclusiv marginea inferioar teoretic asupra complexitii sortrii
prezentate aici. Marginile inferioare pentru sortare folosind generalizrile modelului arborelui de
decizie au fost studiate exhaustiv de ctre Ben-Or [23].
Knuth i atribuie lui H.H. Seward inventarea sortrii prin numrare n 1954 i a ideii de
combinare a sortrii prin numrare cu ordonare pe baza cifrelor. Ordonarea pe baza cifrelor dup
cea mai puin semnificativ cifr pare s fie un algoritm popular, larg utilizat de ctre operatorii
mainilor mecanice de sortare a cartelelor. Conform lui Knuth, prima referin publicat a
metodei este un document din 1929 aparinnd lui L.J. Comrie, ce descrie echipamentul pentru
cartele perforate. Ordonarea pe grupe a fost utilizat ncepnd cu 1956, cnd ideea de baz a
fost propus de E.J. Isaac i R.C. Singleton.
10 Mediane i statistici de ordine

A i-a statistic de ordine a unei mulimi de n elemente este al i-lea cel mai mic element.
De exemplu, minimul unei mulimi de elemente este prima statistic de ordine (i = 1), iar
maximul este a n-a statistic de ordine (i = n). Intuitiv, o median este punctul de la
jumtatea drumului unei mulimi. Cnd n este impar, mediana este unic, i apare pe poziia
i = (n + 1)/2. Cnd n este par, exist dou mediane, care apar pe poziiile i = n/2 i i = n/2 + 1.
Astfel, indiferent de paritatea lui n, medianele apar pe poziiile i = b(n + 1/2)c (mediana
inferioar) i i = d(n + 1/2)e (mediana superioar). Pentru simplificare, vom folosi de acum
nainte termenul median cu sensul de median inferioar.
Acest capitol trateaz problema selectrii celei de-a i-a statistici de ordine dintr-o mulime
de n numere distincte. Presupunem c mulimea conine numere distincte, dei teoretic tot ce
facem se extinde la situaia n care o mulime conine valori nu neaprat distincte. Problema
seleciei poate fi enunat riguros dup cum urmeaz:

Date de intrare: O mulime A de n numere (distincte) i un numr i, avnd proprietatea


1 i n.
Date de ieire: Elementul x A, care este mai mare dect exact i 1 alte elemente ale lui A.

Problema seleciei poate fi rezolvat n timp O (n lg n), ntruct numerele se pot sorta
utiliznd heapsort sau sortarea prin interclasare i apoi, indexnd, pur i simplu al i-lea element
din tabloul de ieire. Exist totui i algoritmi mai rapizi.
n seciunea 10.1 se examineaz problema selectrii minimului i maximului unei mulimi
de elemente. Mai interesant este problema seleciei generale, detaliat n urmtoarele dou
seciuni. Seciunea 10.2 analizeaz un algoritm practic care atinge o margine O(n) n timp
mediu de execuie. Seciunea 10.3 conine un algoritm de interes mai mult teoretic care atinge
timpul de execuie O(n) n cel mai defavorabil caz.

10.1. Minim i maxim


Cte comparaii sunt necesare pentru a determina minimul unei mulimi de n elemente?
Putem obine uor o margine superioar de n 1 comparaii: se examineaz pe rnd fiecare
element al mulimii i se reine cel mai mic element vizitat pn la momentul curent. n procedura
Minim presupunem c mulimea const din tabloul A, unde lungime [A] = n.

Minim(A)
1: min A [1]
2: pentru i 2, lungime[A] execut
3: dac min > A[i] atunci
4: min A[i]
5: returneaz min

Determinarea maximului poate fi realizat la fel de bine i prin n 1 comparaii.


10.2. Selecia n timp mediu liniar 159

Este acesta cel mai bun algoritm? Da, ntruct putem obine o margine inferioar pentru
n1 comparaii n problema determinrii minimului. S ne gndim la un algoritm care determin
minimul n cazul unui campionat. Fiecare comparaie reprezint un meci al campionatului pe care
l ctig cel mai mic dintre dou elemente. Observaia cheie este c fiecare element, cu excepia
nvingtorului, trebuie s piard cel puin un meci. Deci, pentru a determina minimul, sunt
necesare n 1 comparaii, iar algoritmul Minim este optim n privina numrului de comparaii
realizate.
Un punct interesant al analizei este determinarea numrului mediu de execuii ale liniei 4.
Problema 6-2 v cere s demonstrai c aceast medie este (lg n).

Minim i maxim simultane


n unele aplicaii trebuie gsite simultan minimul i maximul unei mulimi de n elemente.
De exemplu, un program grafic poate avea nevoie s scaleze o mulime de date (x, y) pentru a le
afia pe un ecran dreptunghiular sau pe un alt dispozitiv de ieire. Pentru a realiza acest lucru,
programul trebuie, mai nti, s determine minimul i maximul fiecrei coordonate.
Nu este prea dificil de proiectat un algoritm care s poat gsi att minimul ct i maximul
a n elemente folosind numrul asimptotic optimal de comparaii (n). Se determin minimul i
maximul independent, folosind n1 comparaii pentru fiecare, deci un total de 2n2 comparaii.
De fapt, sunt suficiente numai 3 dn/2e 2 comparaii pentru a determina att minimul ct
i maximul. Prima pereche necesit numai o comparaie pentru a stabili valorile iniiale pentru
minimul i maximul curente, ceea ce justific termenul 2. n acest scop, pstrm minimul i
maximul gsite pe msur ce se lucreaz. n loc s prelucrm fiecare element de intrare compa-
rndu-l cu minimul i maximul curente cu un cost de dou comparaii per element, vom prelucra
perechi de elemente. Comparm perechile de elemente ale datelor de intrare, mai nti ntre ele,
apoi comparm elementul mai mic cu minimul curent i elementul mai mare cu maximul curent,
cu un cost de trei comparaii pentru fiecare dou elemente.

Exerciii
10.1-1 Artai c al doilea cel mai mic dintre n elemente poate fi determinat, n cel mai
defavorabil caz, prin n + dlg ne 2 comparaii. (Indicaie: Gsii i cel mai mic element.)

10.1-2 ? Artai c, n cel mai defavorabil caz, sunt necesare d3n/2e 2 comparaii pentru a
determina maximul i minimul a n elemente. (Indicaie: Studiai cte numere pot fi potenial
maximul sau minimul, i cercetati cum afecteaz o comparaie aceste calcule.)

10.2. Selecia n timp mediu liniar


Problema general a seleciei pare mai dificil dect simpla problem a gsirii unui minim, i
n plus, surprinztor, timpul asimptotic de execuie pentru ambele probleme este acelai: (n).
n aceast seciune vom prezenta un algoritm divide i stpnete pentru problema seleciei.
Algoritmul Selecie-Aleatoare este modelat pe baza algoritmului de sortare rapid din
capitolul 8. Ca i la sortarea rapid, ideea este de a partiiona recursiv tabloul de intrare.
Spre deosebire de sortarea rapid, care prelucreaz recursiv ambele componente ale partiiei,
160 Capitolul 10 Mediane i statistici de ordine

Selecie-Aleatoare lucreaz numai cu o component. Aceast diferen se evideniaz la


analiz: n timp ce sortarea rapid are un timp mediu de execuie de (n lg n), timpul mediu al
algoritmului Selecie-Aleatoare este (n).
Selecie-Aleatoare folosete procedura Partiie-Aleatoare, prezentat n seciunea
8.3. Astfel, ca i Quicksort-Aleator, este un algoritm aleator, ntruct comportamentul su
este parial determinat de datele de ieire ale unui generator de numere aleatoare. Codul urmtor
pentru Selecie-Aleatoare returneaz al i-lea cel mai mic element al tabloului A [p..r].
Selecie-Aleatoare(A, p, r, i)
1: dac p = r atunci
2: returneaz A[p]
3: q Partiie-Aleatoare(A, p, r)
4: k q p + 1
5: dac i k atunci
6: returneaz Selecie-Aleatoare(A, p, q, i)
7: altfel
8: returneaz Selecie-Aleatoare(A, q + 1, r, i k)

Dup execuia procedurii Partiie-Aleatoare din linia 3 a algoritmului, tabloul A [p..r] este
partiionat n dou subtablouri nevide A [p..q] i A [q + 1..r] astfel nct fiecare element al lui
A [p..q] este mai mic dect fiecare element al lui A [q + 1..r]. Linia 4 a algoritmului calculeaz
numrul k de elemente al subtabloului A [p..q]. Algoritmul determin n care dintre subtablourile
A [p..q] i A [q + 1..r] se situeaz al i-lea cel mai mic element. Dac i k, atunci elementul dorit
se situeaz n partea inferioar a partiiei, i este selectat recursiv din subtabloul accesat n linia
6. Dac i > k, elementul dorit se situeaz n partea superioar a partiiei. ntruct cunoatem
deja k valori mai mici dect al i-lea cel mai mic element al lui A[p..q] adic elementele lui
A[p..r] elementul cutat este al i k-lea cel mai mic element al lui A[q + 1..r], care este gsit
recursiv n linia 8.
Timpul de execuie, n cazul cel mai defavorabil, pentru Selecie-Aleatoare este (n2 ),
chiar i pentru gsirea minimului, pentru c am putea fi extrem de nenorocoi i s partiionm
n jurul celui mai mare element rmas. Algoritmul lucreaz bine n cazul mediu, dei, deoarece
este aleator, nu exist date de intrare particulare care s provoace comportamentul celui mai
defavorabil caz.
Putem obine o margine superioar T (n) pe timpul mediu necesar algoritmului Selecie-
Aleatoare pe un tablou de intrare de n elemente, dup cum urmeaz. Am vzut n seciunea
8.4 c algoritmul Partiie-Aleatoare produce o partiie a crei component inferioar are un
singur element cu probabilitatea 2/n i i elemente cu probabilitatea 1/n pentru i = 2, 3, ..., n 1.
Presupunnd c T (n) este monoton cresctor, n cazul cel mai defavorabil Selecie-Aleatoare
este ntotdeauna nenorocos n sensul c cel de-al i-lea element este localizat pe zona cea mai mare
a partiiei. Astfel, obinem recurena
n1
!
1 X
T (n) T (max (1, n 1)) + T (max (k, n k)) + O(n)
n
k=1

n1
X n1
1 2 X
T (n 1) + 2 T (k) + O(n) = T (k) + O(n).
n n
k=dn/2e k=dn/2e
10.3. Selecia n timp liniar n cazul cel mai defavorabil 161

A doua linie rezult din prima ntruct max(1, n 1) = n 1 i



k dac k dn/2e,
max(k, n k) =
n k dac k < dn/2e.
Dac n este impar, fiecare termen T (dn/2e) , T (dn/2e + 1) , . . . , T (n 1) apare de dou ori n
sum, i chiar dac n este par, fiecare termen T (dn/2e + 1) , T (dn/2e + 2) , ..., T (n 1) apare
de dou ori, iar termenul T (dn/2e) apare o singur dat. n oricare dintre cele dou cazuri, suma
de pe prima linie este mrginit superior de suma de pe a doua linie. n cazul cel mai defavorabil,
T (n 1) = O(n2 ), i astfel termenul n1 T (n 1) poate fi incorporat de ctre termenul O(n).
Demonstrm recurena prin substituie. Presupunem c T (n) cn pentru unele constante c
care satisfac condiiile iniiale ale recurenei. Folosind aceast ipotez de inducie, avem

n1 n1 dn/2e1
2 X 2c X X
T (n) ck + O(n) = k k + O(n)
n n
k=dn/2e k=1 k=1
l n m
2c 1 1 l n m
= (n 1) n 1 + O(n)
n 2 2 2 2

c n n 3 1
c (n 1) 1 + O(n) = c n + O(n) cn,
n 2 2 4 2
ntruct putem alege un c suficient de mare pentru ca c(n/4 + 1/2) s domine termenul O(n).
Astfel, orice statistic de ordine i n special mediana, poate fi determinat ntr-un timp
mediu liniar.

Exerciii
10.2-1 Scriei versiunea iterativ a algoritmului Selecie-Aleatoare.

10.2-2 S presupunem c folosim Selecie-Aleatoare pentru a selecta elementul minim al


unui tablou A = h3, 2, 9, 0, 7, 5, 4, 8, 6, 1i. Descriei o secven de partiii care se genereaz, n
cazul cel mai defavorabil, de ctre Selecie-Aleatoare.

10.2-3 Amintim c dac exist elemente egale atunci procedura Partiie-Aleatoare parti-
ioneaz subtabloul A[p..r] n dou subtablouri nevide A[p..q] i A[q + 1..r], astfel nct fiecare
element din A[p..q] este mai mic sau egal dect fiecare element din A[q + 1..r]. Dac exist
elemente egale, mai funcioneaz corect procedura Selecie-Aleatoare?

10.3. Selecia n timp liniar n cazul cel mai defavorabil


S examinm acum un algoritm de selecie al crui timp de execuie pentru cazul cel mai
defavorabil este O(n). La fel ca i Selecie-Aleatoare, algoritmul Selecie gsete elemen-
tul dorit partiionnd recursiv un tablou de intrare. Ideea algoritmului este de a garanta o
partiionare bun a tabloului. Selecie utilizeaz algoritmul determinist Partiie din algorit-
mul de sortare rapid (vezi seciunea 8.1), modificat astfel nct s preia ca parametru de intrare
elementul n jurul cruia este efectuat partajarea.
162 Capitolul 10 Mediane i statistici de ordine

Algoritmul Selecie determin al i-lea cel mai mic element al unui tablou de intrare de n
elemente, efectund urmtorii pai. (Dac n = 1, atunci Selecie returneaz singura dat de
intrare a ei, ca fiind a i-a cea mai mic valoare.)
1. Se mpart cele n elemente ale tabloului de intrare n bn/5c grupe de cte 5 elemente fiecare
i cel mult un grup s conin restul de n mod 5 elemente.
2. Se determin mediana fiecruia din cele dn/5e grupe cu sortarea prin inserie, ordonnd
elementele fiecrui grup (care are cel mult 5 elemente) apoi se aleg medianele din listele
sortate, corespunztoare grupelor. (Dac grupul are un numr par de elemente se va
considera cea mai mare dintre cele dou mediane.)
3. Se utilizeaz recursiv Selecie pentru a gsi mediana x din cele dn/5e mediane gsite la
pasul 2.
4. Se partiioneaz tabloul de intrare n jurul medianei medianelor x, utiliznd o versiune
modificat a algoritmului Partiie. Fie k numrul de elemente de pe latura inferioar a
partiiei, astfel nct s fie n k elemente pe latura superioar.
5. Se utilizeaz recursiv Selecie pentru a gsi al i-lea cel mai mic element de pe latura
inferioar dac i k, sau al (i k)-lea cel mai mic element de pe latura superioar dac
i > k.
Pentru a analiza timpul de execuie a lui Selecie, determinm mai nti o margine inferioar
a numrului de elemente care sunt mai mari dect elementul de partiionare x. Figura 10.1 ajut
la vizualizarea acestei contabilizri. Cel puin jumtate dintre medianele gsite la pasul 2 sunt
mai mari sau egale cu mediana medianelor, x. Astfel, cel puin jumtate din cele dn/5e grupe au
cte 3 elemente mai mari dect x, cu excepia singurului grup care are mai puin de 5 elemente
dac n nu este divizibil cu 5, i a singurului grup care l conine pe x. Eliminnd aceste dou
grupuri, rezult c numrul elementelor mai mari dect x este cel puin
l m
1 n 3n
3 2 6.
2 5 10
Similar, numrul elementelor mai mici dect x este cel puin 3n/10 6. Astfel, n cel mai
defavorabil caz, Selecie este apelat recursiv la pasul 5 pentru cel mult 7n/10 + 6 elemente.
Putem construi o recuren pentru timpul de execuie T (n), n cazul cel mai defavorabil, al
algoritmului Selecie. Paii 1, 2 i 4 necesit timpul O(n). (Pasul 2 const din O(n) apeluri
pentru sortarea prin inserie pe mulimi de mrimea O(1).) Pasul 3 necesit timpul T (dn/5e), iar
pasul 5 necesit cel mult T (7n/10 + 6), presupunnd c T este monoton cresctor. De reinut c
7n/10 + 6 < n pentru n > 20 i c orice date de intrare de 80 sau mai puine elemente necesit
timpul O(1). Obinem deci recurena

(1) dac n 80,
T (n)
T (dn/5e) + T (7n/10 + 6) + O(n) dac n > 80.
Demonstrm prin substituie c timpul de execuie este liniar. Presupunem c T (n) cn pentru
o anume constant c i toi n 80. Substituind aceast ipotez inductiv n partea dreapt a
recurenei obinem
T (n) c dn/5e + c(7n/10 + 6) + O(n) cn/5 + c + 7cn/10 + 6c + O(n)
9cn/10 + 7c + O(n) cn,
10.3. Selecia n timp liniar n cazul cel mai defavorabil 163

Figura 10.1 Analiza algoritmului Selecie. Cele n elemente sunt reprezentate prin mici cercuri, i
fiecare grup ocup o coloan. Medianele grupurilor sunt colorate n alb, iar mediana medianelor x este
etichetat. Sgeile sunt trasate de la elementele mai mari spre cele mai mici; se poate vedea c cele 3
elemente din dreapta lui x din fiecare grup de cte 5 sunt mai mari dect x, i c cele 3 elemente din
stnga lui x din fiecare grup de cte 5 elemente sunt mai mici dect x. Elementele mai mari dect x
sunt situate pe un fond mai nchis.

ntruct putem s alegem un c suficient de mare astfel nct c(n/10 7) s fie mai mare dect
funcia descris de termenul O(n) pentru orice n > 80. Timpul de execuie T (n) al algoritmului
Selecie, n cazul cel mai defavorabil, este deci liniar.
La fel ca i n cazul sortrii prin comparaii (vezi seciunea 9.1), Selecie i Selecie-
Aleatoare determin informaia despre ordinea relativ a elementelor numai prin compararea
lor. Astfel, timpul liniar nu este un rezultat al unor presupuneri despre datele de intrare, cum a
fost cazul algoritmilor de sortare din capitolul 9. Sortarea necesit timpul (n lg n) n modelul
bazat pe comparaii, chiar n cazul mediu (vezi problema 9-1), i astfel metoda sortrii i indexrii
prezentat n introducerea acestui capitol este asimptotic ineficient.

Exerciii
10.3-1 n algoritmul Selecie elementele de intrare sunt mprite n grupe de cte 5. Va mai
funciona algoritmul n timp liniar dac ele sunt mprite n grupe de cte 7? Argumentai c
Selecie nu se va executa n timp liniar dac grupele conin cte 3 elemente.

10.3-2 Analizai procedura Selecie i artai c numrul elementelor mai mari dect mediana
medianelor x i numrul elementelor mai mici dect x este cel puin dn/4e dac n 38.

10.3-3 Artai cum poate fi modificat algoritmul de sortare rapid astfel nct s se execute n
timpul O(n lg n) n cel mai defavorabil caz.

10.3-4 ? S presupunem c un algoritm utilizeaz numai comparaii pentru a determina al


i-lea cel mai mic element dintr-o mulime de n elemente. Artai c el poate determina i cele
i 1 elemente mai mici i cele n i elemente mai mari, fr a mai face nici o comparaie n plus.

10.3-5 Fiind dat o procedur de tip cutie neagr, care n cazul cel mai defavorabil determin
mediana n timp liniar, proiectai un algoritm simplu, care s rezolve problema seleciei pentru
orice statistic de ordine n timp liniar.
164 Capitolul 10 Mediane i statistici de ordine

Figura 10.2 Vrem s determinm poziia conductei de petrol est-vest care mimimizeaz lungimea
total a racordurilor nord-sud.

10.3-6 k-cuantilele unei mulimi de n elemente sunt cele k 1 statistici de ordine care mpart
mulimea sortat n k mulimi de mrimi egale (cu cel puin un element). Realizai un algoritm
n timpul O (n lg k) care s listeze k-cuantilele unei mulimi.

10.3-7 Descriei un algoritm de timp O(n) care, fiind dat o mulime S de n numere distincte i
un ntreg pozitiv k n, determin cele k numere din S care sunt cele mai apropiate de mediana
lui S.

10.3-8 Fie X [1..n] i Y [1..n] dou tablouri ce conin fiecare n numere deja sortate. Scriei un
algoritm de timp O(lg n) care gsete mediana tuturor celor 2n elemente din tablourile X i Y .

10.3-9 Profesorul Olay acord consultaii unei companii petroliere, care plnuiete realizarea
unei mari conducte ce trece de la est la vest printr-un cmp de petrol cu n puuri. La fiecare pu
trebuie conectat direct la conducta principal o conduct de pompare (racord) care s fie de-a
lungul celui mai scurt drum (fie nord, fie sud), ca n figura 10.2. Cunoscndu-se coordonatele
x i y ale puurilor, cum trebuie profesorul s localizeze optim conducta principal (cea care
minimizeaz lungimea total a racordurilor)? Artai c poziia optim poate fi determinat n
timp liniar.

Probleme
10-1 Cele mai mari i numere n ordine sortat
Fiind dat o mulime de n numere, dorim s gsim cele mai mari i numere n ordinea sortat,
folosind un algoritm bazat pe comparaii. Descriei un algoritm optim care implementeaz fiecare
dintre metodele urmtoare, i analizai timpii de execuie ai metodelor n funcie de n i i.
Probleme 165

a. Sortai numerele i listai cele mai mari i numere.


b. Construii o coad de prioriti din numere i apelai Extrage-Max de i ori.
c. Utilizai un algoritm de statistic de ordine pentru a gsi al i-lea cel mai mare numr,
partiionai i sortai cele mai mari i numere.

10-2 Mediana ponderat


Pentru
Pn n elemente distincte x1 , x2 , . . . , xn cu ponderile pozitive w1 , w2 , . . . , wn , astfel nct
i=1 wi = 1, mediana ponderat este elementul xk ce satisface condiiile
X 1
wi <
x <x
2
i k

i
X 1
wi .
xi >xk
2

(Aceasta este de fapt mediana inferioar ponderat; mediana superioar ponderat se


definete similar.)
a. Argumentai c mediana elementelor x1 , x2 , . . . , xn este mediana ponderat a lui xi cu
ponderile wi = 1/n pentru i = 1, 2, . . . , n.
b. Artai cum se calculeaz mediana ponderat a n elemente n timpul O(n lg n) n cazul cel
mai defavorabil, folosind sortarea.
c. Artai cum se calculeaz mediana ponderat n timpul (n) n cazul cel mai defavorabil
folosind un algoritm de timp mediu liniar cum ar fi, de exemplu, Selecie din seciunea
10.3.
Problema amplasrii oficiului potal este definit n modul urmtor. Se consider n puncte
p1 , p2 , ..., pn cu ponderile asociate w1 , w2 , ..., wn . Se dorete determinarea
Pn unui punct p (nu
neaprat unul din punctele de intrare) care s minimizeze suma i=1 wi d(p, pi ), unde d(a, b)
este distana dintre punctele a i b.
d. Argumentai c mediana ponderat este cea mai bun soluie pentru problema amplasrii
oficiului potal n cazul unidimensional n care punctele sunt numere reale simple, iar
distana dintre punctele a i b este d(a, b) = |a b|.
e. Gsii cea mai bun soluie pentru problema amplasrii oficiului potal n cazul bidi-
mensional, n care punctele sunt perechi de coordonate (x, y) i distana dintre punctele
a = (x1 , y1 ) i b = (x2 , y2 ) este distana Manhattan: d (a, b) = |x1 x2 | + |y1 y2 |.

10-3 Statistici de ordin mic


Numrul de comparaii T (n) n cazul cel mai defavorabil folosit de ctre procedura Selecie
pentru a alege statistica de a i-a ordine din n numere s-a demonstrat c satisface relaia T (n) =
(n), dar constanta ascuns de notaia este destul de mare. Cnd i este mic n raport cu n
se poate implementa o procedur diferit care utilizeaz Selecie ca o subrutin, dar face mai
puine comparaii n cazul cel mai defavorabil.
166 Capitolul 10 Mediane i statistici de ordine

a. Descriei un algoritm care folosete Ui (n) comparaii pentru a determina al i-lea cel mai
mic element dintre n elemente, unde i n/2 i

T (n) dac n 2i,
Ui (n) =
n/2 + Ui (n/2) + T (2i) n caz contrar.

(Indicaie: ncepei cu bn/2c comparaii pe perechi disjuncte i apelai procedura recursiv


pentru mulimea coninnd elementul mai mic din fiecare pereche.)
b. Artai c Ui (n) = n + O (T (2i) lg (n/i)).
c. Artai c dac i este constant, atunci Ui (n) = n + O (lg n).
d. Artai c dac i = n/k pentru k 2, atunci Ui (n) = n + O (T (2n/k) lg k).

Note bibliografice
Algoritmul de timp liniar n cel mai defavorabil caz pentru determinarea medianei a fost
inventat de ctre Blum, Floyd, Pratt, Rivest i Tarjan [29]. Versiunea algoritmului pentru un timp
mediu rapid se datoreaz lui Hoare [97]. Floyd i Rivest [70] au dezvoltat o versiune mbuntit
a timpului mediu care partiioneaz n jurul unui element selectat recursiv dintr-o mostr mic
de elemente.
III Structuri de date
Introducere
Mulimea ca noiune fundamental este la fel de important n informatic ca i n matema-
tic. n timp ce mulimile matematice sunt nemodificabile, mulimile manipulate de algoritmi
pot crete, descrete sau, n restul cazurilor,se pot modifica n timp. Astfel de mulimi se numesc
dinamice. Urmtoarele cinci capitole prezint tehnici de baz pentru reprezentarea mulimilor
dinamice finite i pentru manipularea lor de ctre calculator.
n funcie de algoritmi, sunt necesare diferite tipuri de operaii pentru a fi executate asupra
mulimilor. De exemplu, muli algoritmi au nevoie doar de posibilitatea de a insera elemente
ntr-o mulime, de a terge elemente dintr-o mulime sau de a testa apartenena la o mulime.
O mulime dinamic ce suport aceste operaii este numit dicionar . Ali algoritmi necesit
operaii mai complicate. De exemplu, cozile de prioritate, care sunt introduse n capitolul 7 n
contextul structurii de date ansamblu, suport operaiile de inserare a unui element i extragere a
celui mai mic element dintr-o mulime. Deci nu e surprinztor faptul c cea mai bun modalitate
de a implementa o mulime dinamic depinde de operaiile pe care trebuie s le ofere.

Elementele unei mulimi dinamice


ntr-o implementare tipic a unei mulimi dinamice, fiecare element este reprezentat de un
obiect ale crui cmpuri pot fi examinate i manipulate dac avem un pointer (o referin) la
acel obiect (capitolul 11 prezint implementarea obiectelor i pointerilor n medii de programare
care nu le conin ca tipuri de date de baz). Unele categorii de mulimi dinamice presupun
c un cmp al obiectului este un cmp cheie, de identificare. Dac toate cheile sunt diferite,
mulimea dinamic poate fi privit ca o mulime de valori ale cheilor. Obiectul poate conine
date adiionale, care sunt gestionate n alte cmpuri ale obiectului, dar sunt de fapt neutilizate
de ctre implementarea mulimii. De asemenea, obiectul poate avea cmpuri ce sunt manipulate
de ctre operaiile mulimilor, aceste cmpuri putnd conine date sau referine spre alte obiecte
din mulime.
Unele mulimi dinamice presupun c valorile cheilor sunt alese dintr-o mulime total ordonat,
ca de exemplu mulimea numerelor reale sau mulimea tuturor cuvintelor aflate n ordine (uzual)
lexicografic. (O mulime total ordonat satisface proprietatea de trihotomie, definit la pagina
27). O ordine total ne permite s definim, de exemplu, cel mai mic element n mulime sau s
vorbim despre urmtorul element mai mare dect un element dat din mulime.

Operaii pe mulimi dinamice


Operaiile pe o mulime dinamic pot fi mprite n dou categorii: interogri , care re-
turneaz informaii despre mulime sau operaii de modificare, care modific mulimea. n
continuare se prezint o list a operaiilor uzuale. Orice aplicaie specific necesit n general
doar implementarea unora dintre ele.

Caut(S,k) O interogare care, fiind date o mulime S i o valoare cheie k, returneaz un pointer
x la un element din S astfel nct cheie[x] = k sau nil dac nu exist un astfel de element
n S.
Introducere 169

Insereaz(S,x) O operaie de modificare care adaug la mulimea S elementul referit de x.


n mod obinuit se presupune c toate cmpurile din elementul x necesare implementrii
mulimii au fost iniializate n prealabil.

terge(S,x) O operaie de modificare care, fiind dat un pointer x la un element din mulimea
S, terge x din S. (Observai c aceast operaie folosete un pointer la un element x i nu
o valoare a cheii).

Minim(S) O interogare pe o mulime total ordonat S care returneaz elementul din mulimea
S cu cea mai mic valoare a cheii.

Maxim(S) O interogare pe o mulime total ordonat S care returneaz elementul din mulimea
S cu cea mai mare valoare a cheii.

Succesor(S,x) O interogare care, fiind dat un element x a crui cheie este dintr-o mulime S
total ordonat, returneaz elementul urmtor mai mare dect x din S sau nil dac x este
elementul maxim.

Predecesor(S,x) O interogare care, fiind dat un element x a crui cheie este dintr-o mulime
S total ordonat, returneaz elementul urmtor mai mic dect x din S sau nil dac x este
elementul minim.

Interogrile Succesor i Predecesor sunt deseori extinse la mulimi cu elemente nedis-


tincte. Pentru o mulime cu n chei, presupunerea obinuit este c un apel al lui Minim urmat
de n 1 apeluri ale lui Succesor enumer elementele din mulime n ordinea sortrii.
Timpul necesar pentru a executa o operaie asupra mulimilor este, n mod obinuit, msurat
n termenii mrimii mulimii, dat ca unul dintre argumente. De exemplu, capitolul 14 descrie
o structur de date ce poate realiza oricare dintre operaiile descrise mai sus pe o mulime de
dimensiune n n timpul O(lg n).

Sumarul prii a treia


Capitolele 1115 descriu diferite structuri de date ce pot fi folosite pentru a implementa
mulimi dinamice; multe dintre acestea vor fi utilizate ulterior la construirea unor algoritmi
eficieni pentru o diversitate de probleme. O alt structur de date important ansamblul a
fost deja introdus n capitolul 7.
Capitolul 11 prezint fundamentele lucrului cu structuri de date simple ca: stive, cozi, liste
nlnuite i arbori cu rdcin. De asemenea, se arat cum pot fi implementate obiectele sau
referinele n medii de programare care nu le posed ca primitive. O mare parte din acest material
ar trebui s fie familiar tuturor celor care au studiat un curs introductiv n programare.
Capitolul 12 introduce tabele de dispersie (hash), care au operaii pentru dicionare:
Insereaz, terge, Caut. n cazul cel mai nefavorabil, dispersia necesit timpul (n) pentru
a executa o operaie Caut, pe cnd timpul prevzut pentru operaiile de dispersie este O(1).
Analiza dispersiei se bazeaz pe probabiliti, dar cea mai mare parte a capitolului nu necesit
cunotine despre acest subiect.
Arborii de cutare binar, prezentai n capitolul 13 au toate operaiile pe mulimi dinamice
descrise mai sus. n cazul cel mai defavorabil, fiecare operaie necesit un timp (n) pe un arbore
cu n elemente, dar pe un arbore binar de cutare construit aleator, timpul mediu pentru fiecare
170

operaie este O(lg n). Arborii de cutare binar au rol de baz pentru multe alte structuri de
date.
Arborii rounegru, o variant a arborilor de cutare binar, sunt introdui n capitolul 14.
Spre deosebire de arborii de cutare binar obinuii, arborii rounegru prezint garania unei
execuii bune: operaiile necesit un timp O(lg n) n cazul cel mai defavorabil. Un arbore rou
negru este un arbore de cutare echilibrat; capitolul 19 prezint un alt tip de arbori de cutare
echilibrai, numii Barbori. Dei mecanismul arborilor rounegru este ntr-o oarecare msur
greu de urmrit, majoritatea proprietilor lor se poate deduce din capitolul respectiv, fr a
studia mecanismul n detaliu. Oricum, parcurgerea codului poate fi instructiv n sine.
n capitolul 15 vom arta cum se pot mbogi arborii rou negru pentru a suporta alte
operaii, n afara celor de baz prezentate mai sus. n primul rnd, i vom mbogi astfel nct
s putem pstra dinamic o statistic de ordine pentru o mulime de chei. Apoi, i vom mbogi
ntr-o manier diferit pentru a memora intervale de numere reale.
11 Structuri de date elementare

n acest capitol vom examina reprezentarea mulimilor dinamice ca structuri de date simple
care utilizeaz referine. Dei multe structuri de date complexe pot fi modelate folosind pointeri,
le vom prezenta doar pe cele elementare: stive, cozi, liste nlnuite i arbori cu rdcin. De
asemenea, vom prezenta o metod prin care obiectele i pointerii pot fi sintetizai din tablouri.

11.1. Stive i cozi


Stivele i cozile sunt mulimi dinamice n care elementul care este eliminat din mulime de
ctre operaia terge este prespecificat. ntr-o stiv, elementul ters din mulime este elementul
cel mai recent inserat: stiva implementeaz principiul ultimul sosit, primul servit (last-in,
first-out) sau LIFO. Similar, ntr-o coad, elementul ters este ntotdeauna cel care a stat n
mulime cel mai mult (primul introdus): coada implementeaz principiul primul sosit, primul
servit (first-in, first-out) sau FIFO. Exist mai multe modaliti eficiente de a implementa
stivele i cozile cu ajutorul calculatorului. n aceast seciune vom arta cum se pot folosi
tablourile simple pentru a implementa fiecare dintre aceste structuri.

Stive
Operaia Insereaz asupra stivelor este deseori denumit Pune-n-Stiv, iar operaia
terge, care nu cere nici un argument, este deseori numit Scoate-Din-Stiv. Aceste nume
sunt aluzii la stivele fizice, ca de exemplu un vraf de farfurii. Ordinea n care sunt luate farfuriile
din vraf este ordinea invers n care au fost introduse n vraf, deoarece doar ultima farfurie este
accesibil.
Aa cum se vede n figura 11.1, o stiv cu cel mult n elemente poate fi implementat printr-
un tablou S[1..n]. Tabloul are un atribut v arf [S] care este indicele celui mai recent introdus
element. Stiva const din elementele S[1..v arf [S]], unde S[1] este elementul de la baza stivei, iar
S[varf [S]] este elementul din vrful stivei.
Cnd v arf [S] = 0, stiva nu conine nici un element i deci este vid. Se poate testa dac
stiva este vid prin operaia de interogare Stiv-Vid.
Dac se ncearc extragerea (se apeleaz operaia Scoate-Din-Stiv) unui element dintr-o
stiv vid, spunem c stiva are depire inferioar, care n mod normal este o eroare. Dac
vrf [S ] depete valoarea n, stiva are depire superioar. (n implementarea noastr n
pseudocod, nu ne vom pune problema depirii stivei.)
Fiecare dintre operaiile stivei pot fi implementate prin doar cteva linii de cod.
Stiv-Vid(S )
1: dac vrf[S] = 0 atunci
2: returneaz adevrat
3: altfel
4: returneaz fals
172 Capitolul 11 Structuri de date elementare

Figura 11.1 Implementarea unei stive S printr-un tablou. Elementele stivei apar doar n poziiile
haurate folosind o culoare deschis. (a) Stiva S are 4 elemente. Elementul din vrful stivei este 9.
(b) Stiva S dup apelurile Pune-n-Stiv (S,17) i Pune-n-Stiv(S,3). (c) Stiva S dup ce apelul
Scoate-Din-Stiv (S) a ntors ca rezultat elementul 3, care este cel mai recent introdus. Dei elementul
3 apare n continuare n tabel, el nu mai este n stiv; elementul din vrful stivei este 17.

Pune-n-Stiv(S, x)
1: vrf[S] vrf[S] + 1
2: S[vrf[S]] x

Scoate-Din-Stiv(S)
1: dac Stiv-Vid(S ) atunci
2: eroare depire inferioar
3: altfel
4: vrf[S] vrf[S] - 1
5: returneaz S[vrf[S]+1]

Figura 11.1 ilustreaz modificrile produse n urma apelurilor operaiilor Pune-n-Stiv i


Scoate-Din-Stiv. Fiecare dintre cele trei operaii asupra stivelor necesit un timp O(1).

Cozi
Vom numi Pune-n-Coad operaia Insereaz aplicat asupra unei cozi, iar operaia
terge o vom numi Scoate-Din-Coad; asemntor operaiei Scoate-Din-Stiv aplicat
stivei, Scoate-Din-Coad nu necesit nici un argument. Principiul FIFO, propriu cozii, impune
ca aceasta s opereze asemntor cu un rnd de oameni ce ateapt la un ghieu. Coada are un
cap i o coad. Cnd un element este pus n coad, ocup locul de la sfritul cozii, ca i un
nou venit ce i ia locul la coada rndului. Elementul scos din coad este ntotdeauna cel din
capul cozii, asemntor persoanei din capul rndului care a ateptat cel mai mult. (Din fericire,
nu trebuie s ne ngrijorm din cauza elementelor care se bag n fa.)
Figura 11.2 ilustreaz o modalitate de a implementa o coad avnd cel mult n 1 elemente,
folosind un tablou Q[1..n]. Coada are un atribut cap[Q] care conine indicele capului ei. Atributul
coada[Q] conine indicele noii locaii n care se va insera n coad elementul nou venit. Elementele
din coad se afl n locaiile cap[Q], cap[Q] + 1, ..., coad
a[Q] 1, iar indicii se parcurg circular, n
sensul c locaia 1 urmeaz imediat dup locaia n. Cnd cap[Q] = coad a[Q] coada este goal.
Iniial avem cap[Q] = coad a[Q] = 1. Cnd coada este vid, o ncercare de a scoate un element din
coad cauzeaz o depire inferioar n coad. Cnd cap[Q] = coad a[Q] + 1, coada este plin
i o ncercare de a pune n coad cauzeaz o depire superioar n coad.
n Pune-n-Coad i Scoate-Din-Coad, verificarea erorilor de depire inferioar a fost
omis. (Exerciiul 11.1-4 cere scrierea codului ce verific aceste dou condiii de eroare.)
11.1. Stive i cozi 173

Figura 11.2 O coad implementat utiliznd un tablou Q[1..12]. Elementele cozii apar doar n poziiile
cu haur deschis. (a) Coada are 5 elemente, n locaiile Q[7..11]. (b) Configuraia cozii dup apelurile
Pune-n-Coad (Q,17), Pune-n-Coad(Q,3), Pune-n-Coad(Q,5). (c) Configuraia cozii dup ce
apelul Scoate-Din-Coad(Q) returneaz valoarea cheii 15, ce s-a aflat anterior n capul cozii. Noul
cap are cheia 6.

Pune-n-Coad(Q, x)
1: Q[coada[Q]] x
2: dac coada[Q] = lung[Q] atunci
3: coada[Q] 1
4: altfel
5: coada[Q] coad
a[Q] + 1

Scoate-Din-Coad(Q)
1: x Q[cap[Q]]
2: dac cap[Q] = lung[Q] atunci
3: cap[Q] 1
4: altfel
5: cap[Q] cap[Q] + 1
6: returneaz x

n figura 11.2 sunt ilustrate efectele operaiilor Pune-n-Coad i Scoate-Din-Coad.


Fiecare operaie necesit un timp O(1).

Exerciii
11.1-1 Folosind ca model figura 11.1, ilustrai efectul fiecreia dintre operaiile Pune-
n-Stiv(S, 4), Pune-n-Stiv(S, 1), Pune-n-Stiv(S, 3), Scoate-Din-Stiv(S), Pune-n-
Stiv(S, 8), Scoate-Din-Stiv(S) pe o stiv iniial vid, memorat ntr-un tablou S[1..6].
174 Capitolul 11 Structuri de date elementare

11.1-2 Explicai cum se pot implementa dou stive ntr-un singur tablou A[1..n] astfel nct
nici una dintre stive s nu aib depire superioar, cu excepia cazului n care numrul total de
elemente din ambele stive (mpreun) este n. Operaiile Pune-n-Stiv i Scoate-Din-Stiv
trebuie s funcioneze ntr-un timp O(1).

11.1-3 Folosind ca model figura 11.2, ilustrai efectul fiecreia dintre operaiile Pune-n-
Coad(Q, 4), Pune-n-Coad(Q, 1), Pune-n-Coad(Q, 3), Scoate-Din-Coad(Q), Pune-
n-Coad(Q, 8) i Scoate-Din-Coad (Q) pe o coad Q, iniial vid, a memorat ntr-un tablou
Q[1..6].

11.1-4 Rescriei Pune-n-Coad i Scoate-Din-Coad pentru a detecta depirile unei cozi.

11.1-5 n timp ce stiva permite inserarea i tergerea de elemente doar la un singur capt, iar
coada permite inserarea la un capt i tergerea la cellalt capt, o coad complet permite
inserri i tergeri la ambele capete. Scriei patru proceduri cu timpul de execuie O(1) pentru
inserare de elemente i tergere de elemente la ambele capete ale unei cozi complete implementat
printr-un tablou.

11.1-6 Artai cum se poate implementa o coad prin dou stive. Analizai timpul de execuie
pentru operaiile cozii.

11.1-7 Artai cum se poate implementa o stiv prin dou cozi. Analizai timpul de execuie
pentru operaiile stivei.

11.2. Liste nlnuite


O list nlnuit este o structur de date n care obiectele sunt aranjate ntr-o anumit
ordine. Spre deosebire de tablou, n care ordinea este determinat de indicii tabloului, ordinea
ntr-o list nlnuit este determinat de un pointer coninut n fiecare obiect. Listele nlnuite
asigur o reprezentare mai simpl i mai flexibil pentru mulimi dinamice, suportnd (dei nu
neaprat eficient) toate operaiile descrise la pagina 168.
Dup cum se arat n figura 11.3, fiecare element al unei liste dublu nlnuite L este un
obiect cu un cmp cheie i alte dou cmpuri pointer: urm (urmtor) i prec (precedent). Obiectul
poate conine i alte date. Fiind dat un element x din list, urm[x] indic spre succesorul su din
lista nlnuit, iar prec[x] indic spre predecesorul su. Dac prec[x] = nil atunci elementul x
nu are nici un predecesor i deci e primul element din list, sau capul listei. Dac urm[x] =nil
atunci elementul x nu are succesor i deci este ultimul element sau coada listei. Un atribut
cap[L] refer primul element al listei. Dac cap[L] =nil, lista este vid.
O list poate avea una din urmtoarele forme. Ea poate fi simplu nlnuit sau dublu
nlnuit, poate fi sortat sau nu, i poate fi, sau nu, circular. Dac o list este simplu
nlnuit vom omite pointerul prec din fiecare element. Dac o list este sortat, ordinea
din list corespunde ordinii cheilor memorate n elementele listei; elementul minim este capul
listei, iar elementul maxim este coada listei. Dac lista este nesortat, elementele pot aprea n
orice ordine. ntr-o list circular referina prec a capului listei refer coada iar referina urm
a cozii listei refer capul ei. Astfel, lista poate fi privit ca un inel de elemente. n restul acestei
seciuni vom presupune c listele cu care lucrm sunt nesortate i dublu nlnuite.
11.2. Liste nlnuite 175

Figura 11.3 (a) O list dublu nlnuit L reprezentnd mulimea dinamic {1, 4, 9, 16}. Fiecare
element din list este un obiect avnd cmpuri pentru cheie i doi pointeri (ilustrai prin sgei)
la elementul urmtor, respectiv anterior. Cmpul urm al cozii i cmpul prec al capului sunt nil,
lucru indicat printr-un slash. Atributul cap[L] refer capul listei. (b) Dup execuia lui List-
Insereaz(L, x), unde cheie[x] = 25, capul listei nlnuite este un nou obiect avnd cheia 25. Acest
nou obiect refer vechiul cap avnd cheia 9. (c) Rezultatul apelului List-terge(L, x), unde x refer
obiectul avnd cheia 4.

Cutarea ntr-o list nlnuit


Procedura List-Caut(L, k) gsete primul element avnd cheia k din lista L printr-o
cutare liniar simpl, returnnd pointerul la acest element. Dac n list nu apare nici un
obiect avnd cheia k, atunci se returneaz nil. Pentru lista nlnuit din figura 11.3(a), apelul
List-Caut(L, 4) returneaz un pointer la al treilea element, iar apelul List-Caut(L, 7)
returneaz nil.
List-Caut(L, x)
1: x cap[L]
2: ct timp x 6= nil i cheie[x] 6= k execut
3: x urm[x]
4: returneaz x

Pentru a cuta ntr-o list avnd n obiecte, procedura List-Caut necesit un timp (n)
n cazul cel mai defavorabil, deoarece va trebui s caute n toat lista.

Inserarea ntr-o list nlnuit


Fiind dat un element x al crui cmp cheie a fost iniializat, procedura List-Insereaz l
plaseaz pe x n faa listei nlnuite, dup cum se poate observa n figura 11.3(b).
List-Insereaz(L, x)
1: urm[x] cap[L]
2: dac cap[L] 6= nil atunci
3: prec[cap[L]] x
4: cap[L] x
5: prec[x] nil

Timpul de execuie pentru List-Insereaz pe o list cu n elemente este O(1).


176 Capitolul 11 Structuri de date elementare

tergerea dintr-o list nlnuit


Procedura List-terge elimin un element x dintr-o list nlnuit L. Pentru aceasta,
trebuie transmis ca argument un pointer spre x i x va fi scos din list, actualizndu-se pointerii.
Dac dorim s tergem un element cu o cheie dat, mai nti trebuie s apelm List-Caut
pentru a afla pointerul spre acel element.
List-terge(L, x)
1: dac prec[x] 6= nil atunci
2: urm[prec[x]] urm[x]
3: altfel
4: cap[L] urm[x]
5: dac urm[x] 6= nil atunci
6: prec[urm[x]] prec[x]

Figura 11.3(c) ilustreaz cum se terge un element dintr-o list nlnuit. List-terge se
execut ntr-un timp O(1), dar dac dorim s tergem un element avnd o cheie dat, timpul
necesar pentru cazul cel mai defavorabil este (n), pentru c nainte trebuie s apelm List-
Caut.

Santinele
Codul pentru List-terge ar fi mai simplu dac am ignora condiiile extreme de la capul
i coada listei.
List-terge0 (L, x)
1: urm[prec[x]] urm[x]
2: prec[urm[x]] prec[x]

O santinel este un obiect fictiv care ne permite s simplificm condiiile de la extreme. De


exemplu, s presupunem c n lista L avem la dispoziie un obiect nil[L], care reprezint nil, dar
care are toate cmpurile unui element al listei. De cte ori avem o referin la nil n codul listei,
o vom nlocui cu o referin la santinela nil[L]. Dup cum se observ n figura 11.4, santinela
transform o list dublu nlnuit ntr-o list circular, cu santinela nil[L] plasat ntre cap i
coad; cmpul urm[nil[L]] indic spre capul listei, iar prec[nil[L]] indic spre coad. Similar,
att cmpul urm al cozii ct i cmpul prec al capului indic spre nil[L]. Deoarece urm[nil[L]]
indic spre cap, putem elimina atributul cap[L], nlocuind referinele ctre el cu referine ctre
urm[nil[L]]. O list vid va conine doar santinela, deoarece att urm[nil[L]] ct i prec[nil[L]]
pot fi setate pe nil[L].
Codul pentru List-Caut rmne la fel ca nainte, dar cu referinele spre nil i cap[L]
schimbate dup cum s-a precizat anterior.
List-Caut0 (L, k)
1: x urm[nil[L]]
2: ct timp x 6= nil[L] i cheie[x] 6= k execut
3: x urm[x]
4: returneaz x
11.2. Liste nlnuite 177

Figura 11.4 O list nlnuit L ce folosete o santinel nil[L] (haurat cu negru) este o list dublu
nlnuit obinuit, transformat ntr-o list circular cu nil[L] pus ntre cap i coad. Atributul cap[L]
nu mai este necesar, deoarece capul listei poate fi accesat prin urm[nil[L]]. (a) O list vid. (b) Lista
nlnuit din figura 11.3(a), avnd cheia 9 n capul listei i cheia 1 n coada listei. (c) Lista dup execuia
procedurii List-Insereaz0 (L, x), unde cheie[x] = 25. Noul obiect devine capul listei. (d) Lista dup
tergerea obiectului avnd cheia 1. Noua coad este obiectul avnd cheia 4.

Folosim procedura (cu dou linii de cod) List-terge0 pentru a terge un element din list.
Vom folosi urmtoarea procedur pentru inserarea unui element n list.
List-Insereaz0 (L, x)
1: urm[x] urm[nil[L]]
2: prec[urm[nil[L]]] x
3: urm[nil[L]] x
4: prec[x] nil[L]

Figura 11.4 ilustreaz efectele procedurilor List-Insereaz0 i List-terge0 pe un exemplu.


Rareori santinelele reduc marginile asimptotice de timp pentru operaiile structurilor de date,
dar pot reduce factorii constani. Ctigul pe care l reprezint folosirea santinelelor n cadrul
ciclurilor este de obicei mai mult legat de claritatea codului, dect de vitez; de exemplu, codul
pentru lista nlnuit este simplificat prin utilizarea santinelelor, dar ctigm doar un timp O(1)
n procedurile List-Insereaz0 i List-terge0 . Oricum, n alte situaii, folosirea santinelelor
ajut la restrngerea codului dintr-un ciclu, reducndu-se astfel coeficientul, de exemplu, pentru
n sau n2 din timpul de execuie.
Santinelele trebuie folosite cu discernmnt. Dac avem multe liste mici, spaiul suplimentar
folosit de santinelele acestor liste poate reprezenta o risip semnificativ de memorie. Astfel, n
cartea de fa santinelele se vor folosi doar acolo unde se obine o simplificare semnificativ a
codului.

Exerciii
11.2-1 Se poate implementa operaia Insereaz pentru mulimi dinamice pe o list simplu
nlnuit cu un timp de execuie O(1)? Dar operaia terge?

11.2-2 Implementai o stiv folosind o list simplu nlnuit L. Operaiile Pune-n-Stiv i


Scoate-Din-Stiv ar trebui s necesite tot un timp O(1).
178 Capitolul 11 Structuri de date elementare

11.2-3 Implementai o coad folosind o list simplu nlnuit L. Operaiile Pune-n-Coad


i Scoate-Din-Coad ar trebui s necesite tot un timp O(1).

11.2-4 Implementai operaiile specifice dicionarelor Insereaz, terge i Caut folosind


liste simplu nlnuite, respectiv circulare. Care sunt timpii de execuie pentru aceste proceduri?

11.2-5 Operaia pentru mulimi dinamice Reunete are ca intrare dou mulimi disjuncte S1
i S2 i returneaz mulimea S = S1 S2 ce conine toate elementele din S1 i S2 . Mulimile S1
i S2 sunt de obicei distruse de ctre operaie. Artai cum se poate realiza Reunete ntr-un
timp O(1) folosind o structur de date de tip list, adecvat.

11.2-6 Scriei o procedur care interclaseaz dou liste simplu nlnuite sortate ntr-o singur
list simplu nlnuit sortat fr a folosi santinele. Apoi, scriei o procedur similar folosind
o santinel avnd cheia pentru a marca sfritul fiecrei liste. Comparai simplitatea codului
pentru fiecare din cele dou proceduri.

11.2-7 Creai o procedur nerecursiv de timp de execuie (n) care inverseaz o list simplu
nlnuit avnd n elemente. Procedura va folosi un spaiu suplimentar de memorie de mrime
constant.

11.2-8 ? Explicai cum se pot implementa liste dublu nlnuite folosind o singur valoare
referin np[x] pentru fiecare obiect, n locul celor dou valori uzuale (urm i prec). Se presupune
c toate valorile pointerilor pot fi interpretate ca i ntregi pe k bii i se definete np[x] ca fiind
np[x] = urm[x] XOR prec[x], sau exclusiv pe k bii dintre urm[x] i prec[x]. (Valoarea nil
e reprezentat de 0.) Acordai atenie descrierii informaiei necesare pentru accesarea capului
listei. Artai cum pot fi implementate operaiile Caut, Insereaz i terge pe o astfel de
list. De asemenea, artai cum se poate inversa o astfel de list ntr-un timp O(1).

11.3. Implementarea pointerilor i obiectelor


Cum implementm pointerii i obiectele n limbaje cum ar fi Fortran, care nu asigur lucrul
cu astfel de date? n aceast seciune, vom arta dou modaliti de implementare a structurilor
de date nlnuite fr un tip de date pointer explicit. Vom sintetiza obiectele i pointerii din
tablouri i indici de tablouri.

O reprezentare multi-tablou a obiectelor


O colecie de obiecte care au aceleai cmpuri se poate reprezenta utiliznd cte un tablou
pentru fiecare cmp. De exemplu, figura 11.5 ilustreaz cum se poate implementa lista nlnuit
din figura 11.3(a) prin trei tablouri. Tabloul cheie reine valorile curente ale cheilor din mulimea
dinamic, iar pointerii sunt memorai n tablourile urm i prec. Pentru un indice de tablou x dat,
cheie[x], urm[x] i prec[x] reprezint un obiect n lista nlnuit. ntr-o astfel de implementare,
un pointer x este un simplu indice n tablourile cheie, urm i prec.
n figura 11.3(a), obiectul avnd cheia 4 urmeaz dup obiectul avnd cheia 16 n lista
nlnuit. n figura 11.5, cheia 4 apare n cheie[2], iar cheia 16 apare n cheie[5], deci vom
avea urm[5] = 2 i prec[2] = 5. Dei constanta nil apare n cmpul urm al cozii i n cmpul
11.3. Implementarea pointerilor i obiectelor 179

Figura 11.5 Lista nlnuit din figura 11.3(a) reprezentat prin tablourile cheie, urm i prec. Fiecare
poriune vertical a tablourilor reprezint un singur obiect. Pointerii memorai corespund indicilor
tablourilor ilustrai n partea de sus; sgeile arat cum trebuie interpretai aceti indici. Poziiile cu
haur deschis ale obiectelor conin elementele listei. Variabila L conine indicele capului.

Figura 11.6 Lista nlnuit din figura 11.3(a) i figura 11.5 reprezentat printr-un singur tablou A.
Fiecare element al listei este un obiect care ocup un subtablou continuu de lungime 3 n cadrul tabloului.
Cele trei cmpuri cheie, urm i prec corespund deplasamentelor 0, 1 i respectiv 2. Pointerul la un obiect
este indicele primului element al obiectului. Obiectele coninnd elementele listei sunt haurate deschis,
iar sgeile indic ordinea n list.

prec al capului, de obicei vom folosi un ntreg (ca 0 sau -1) care nu poate reprezenta un indice
valid n tablouri. O variabil L memoreaz indicele capului listei.
n pseudocodul nostru, am folosit paranteze ptrate pentru a nota att indexarea ntr-un
tablou ct i selecia unui cmp (atribut) aparinnd unui obiect. n ambele cazuri, semnificaia
lui cheie[x], urm[x] i prec[x] este consistent relativ la implementare.

O reprezentare a obiectelor printr-un tablou unic


Cuvintele din memoria unui calculator sunt n mod obinuit adresate prin ntregi ntre 0 i
M 1, unde M este un numr ntreg suficient de mare. n multe limbaje de programare, un
obiect ocup o mulime contigu de locaii n memoria calculatorului. Un pointer este pur i
simplu adresa primei locaii de memorie a obiectului iar celelalte locaii de memorie din cadrul
obiectului pot fi indexate adugnd un deplasament la acest pointer.
n medii de programare care nu au tipuri de date pointer explicite putem folosi aceeai
strategie pentru implementarea obiectelor. De exemplu, figura 11.6 ilustreaz cum se poate folosi
un singur tablou A pentru a memora lista nlnuit din figura 11.3(a) i figura 11.5. Un obiect
ocup un subtablou contiguu A[j..k]. Fiecare cmp al obiectului corespunde unui deplasament
din intervalul 0..k j, iar un pointer la obiect este indicele j. n figura 11.6, deplasamentele
180 Capitolul 11 Structuri de date elementare

Figura 11.7 Efectul procedurilor Aloc-Obiect i Elibereaz-Obiect. (a) Lista din figura 11.5
(partea cu haur deschis) i o list liber (partea cu haur nchis). Sgeile indic structura listei
libere. (b) Rezultatul apelului Aloc-Obiect() (care returneaz cheia 4), setnd cheie[4] la 25 i al
apelului List-Insereaz(L, 4). Noul cap al listei libere este obiectul 8, care a fost urm[4] n lista liber.
(c) Dup execuia lui List-terge(L, 5), apelm Elibereaz-Obiect(5). Obiectul 5 devine noul cap
al listei libere, cu obiectul 8 urmndu-i n list.

corespunztoare lui cheie, urm i prec sunt 0, 1, respectiv 2. Pentru a citi valoarea lui prec[i]
pentru un pointer i dat, adugm la valoarea i a pointerului deplasamentul 2, citind astfel A[i+2].
Reprezentarea printr-un singur tablou este flexibil n sensul c permite memorarea de obiecte
cu lungimi diferite n acelai tablou. Problema gestionrii unei astfel de colecii eterogene de
obiecte este mult mai dificil dect problema gestionrii unei colecii omogene, n care toate
obiectele au aceleai cmpuri. Deoarece majoritatea structurilor de date pe care le lum n
considerare sunt compuse din elemente omogene, pentru scopurile noastre va fi suficient s folosim
reprezentarea multi-tablou a obiectelor.

Alocarea i eliberarea obiectelor


Pentru a insera o cheie ntr-o mulime dinamic reprezentat printr-o list dublu nlnuit,
trebuie s alocm un pointer la un obiect neutilizat la momentul respectiv n reprezentarea listei
nlnuite. Prin urmare, este util s inem evidena obiectelor care nu sunt folosite la un moment
dat, n reprezentarea listei nlnuite; astfel, ori de cte ori avem nevoie de un nou obiect, acesta
va fi preluat din lista de obiecte nefolosite. n unele sisteme, un aa numit garbage collector
(colector de reziduuri) este responsabil cu determinarea obiectelor neutilizate. Oricum, sunt
multe aplicaii, suficient de simple astfel nct i pot asuma responsabilitatea de a returna
un obiect neutilizat ctre gestionarul de obiecte nefolosite. Vom studia acum problema alocrii
i eliberrii (sau dealocrii) obiectelor omogene folosind, de exemplu, o list dublu nlnuit
reprezentat prin tablouri multiple.
S presupunem c tablourile din reprezentarea multi-tablou au lungimea m i c la un moment
dat mulimea dinamic conine n m elemente. Atunci n obiecte vor reprezenta elementele
11.3. Implementarea pointerilor i obiectelor 181

Figura 11.8 Dou liste nlnuite L1 (poriunea cu haur deschis) i L2 (cu haur medie) i o list
liber interconectat (cu haur nchis).

curente din mulimea dinamic i restul de m n obiecte sunt libere; obiectele libere pot fi
folosite pentru reprezentarea elementelor ce se vor insera n viitor n mulimea dinamic.
Vom pstra obiectele libere ntr-o list simplu nlnuit, pe care o vom numi list liber.
Lista liber folosete doar tabloul urm, care memoreaz pointerii urm din list. Capul listei libere
este memorat ntr-o variabil global liber. n cazul n care mulimea dinamic reprezentat de
lista nlnuit L este nevid, lista liber se poate ntreese cu lista L, dup cum se observ n
figura 11.7. Observai c fiecare obiect din reprezentare este fie n lista L, fie n lista liber, dar
nu n amndou.
Lista liber este o stiv: urmtorul obiect alocat este cel mai recent eliberat. Putem folosi o
implementare a operaiilor stivei Pune-n-Stiv i Scoate-Din-Stiv folosind o list pentru a
construi procedurile pentru alocarea i, respectiv, eliberarea obiectelor. Presupunem c variabila
global liber folosit n urmtoarele proceduri refer primul element al listei libere.
Aloc-Obiect()
1: dac liber = nil atunci
2: eroare depire de spaiu
3: altfel
4: x liber
5: liber urm[x]
6: returneaz x

Elibereaz-Obiect(x)
1: urm[x] liber
2: liber x

Iniial lista liber conine toate cele n obiecte nealocate. n cazul n care lista liber este
epuizat, procedura Aloc-Obiect semnaleaz o eroare. n mod curent se poate folosi o singur
list liber care s serveasc mai multe liste nlnuite. Figura 11.8 ilustreaz dou liste nlnuite
i o list liber, interconectate prin tablourile cheie, urm i prec.
Cele dou proceduri se execut ntr-un timp O(1), ceea ce le face eficiente. Ele pot fi modificate
astfel nct s funcioneze pentru orice colecie omogen de obiecte, lsnd unul din cmpurile
obiectului s se comporte ca un cmp urm n lista liber.

Exerciii
11.3-1 Desenai o imagine a irului h13, 4, 8, 19, 5, 11i memorat ca o list dublu nlnuit
folosind reprezentarea multi-tablou. Realizai acelai lucru pentru reprezentarea cu un tablou
unic.
182 Capitolul 11 Structuri de date elementare

11.3-2 Scriei procedurile Aloc-Obiect i Elibereaz-Obiect pentru o colecie omogen


de obiecte implementat printr-o reprezentare cu un tablou unic.
11.3-3 De ce nu este necesar s setm sau s resetm cmpurile prec ale obiectelor din
implementarea procedurilor Aloc-Obiect i Elibereaz-Obiect?
11.3-4 De multe ori este de dorit s pstrm toate elementele unei liste dublu nlnuite
ntr-o zon compact la memorare, folosind, de exemplu, primele m locaii din reprezentarea
multi-tablou. (Aceasta este situaia ntr-un mediu de calcul cu memorie virtual, paginat.)
Explicai, cum se pot implementa procedurile Aloc-Obiect i Elibereaz-Obiect astfel
nct reprezentarea s fie compact. Presupunei c nu exist pointeri la elementele listei
nlnuite n afara listei nsei. (Indicaie: Folosii implementarea stivei printr-un tablou.)
11.3-5 Fie L o list dublu nlnuit de lungime m memorat n tablourile cheie, prec i urm de
lungime n. S presupunem c aceste tablouri sunt gestionate de procedurile Aloc-Obiect i
Elibereaz-Obiect, care pstreaz o list liber dublu nlnuit F. Mai presupunem c din
cele n locaii, sunt exact m n lista L i n m n lista liber. Scriei o procedur Compacteaz-
List(L, F ) care, fiind date lista L i lista liber F, mut elementele din L astfel nct ele s ocupe
poziiile 1, 2, ..., m din tablou i ajusteaz lista liber F astfel nct s rmn corect, ocupnd
poziiile m + 1, m + 2, ..., n din tablou. Timpul de execuie pentru procedura scris trebuie s fie
(m) i ea trebuie s utilizeze doar un spaiu suplimentar constant. Dai o argumentare atent
a corectitudinii procedurii scrise.

11.4. Reprezentarea arborilor cu rdcin


Metodele pentru reprezentarea listelor date n seciunea precedent se extind la orice
structur omogen de date. n aceast seciune, vom discuta n mod special problema
reprezentrii arborilor cu rdcin prin structuri de date nlnuite. Vom studia mai nti arborii
binari i apoi vom prezenta o metod pentru arbori cu rdcin n care nodurile pot avea un
numr arbitrar de descendeni.
Vom reprezenta fiecare nod al arborilor printr-un obiect. Ca n cazul listelor nlnuite,
presupunem c fiecare nod conine un cmp cheie. Restul cmpurilor care prezint interes sunt
pointeri ctre celelalte noduri i pot varia n funcie de tipul arborelui.

Arbori binari
Dup cum se observ n figura 11.9 cmpurile p, stnga i dreapta se folosesc pentru a memora
pointerii pentru printe, descendentul stng i descendentul drept al fiecrui nod din arborele
binar T. Dac p[x] = nil, atunci x este rdcina. Dac nodul x nu are descendent stng, atunci
stnga[x] = nil i similar pentru descendentul drept. Rdcina ntregului arbore T este referit
de atributul rdcin[T ]. Dac rdcin[T ] = nil, atunci arborele este vid.

Arbori cu rdcin cu numr nelimitat de ramuri


Schema pentru reprezentarea arborilor binari poate fi extins la orice clas de arbori n care
numrul de descendeni ai fiecrui nod nu depete o constant k: vom nlocui cmpurile stnga
11.4. Reprezentarea arborilor cu rdcin 183

Figura 11.9 Reprezentarea unui arbore binar T. Fiecare nod x are cmpurile p[x] (partea de sus),
stnga[x] (partea din stnga jos) i dreapta[x] (partea din dreapta jos). Cmpurile cheie nu sunt ilustrate.

i dreapta cu f iu1 , f iu2 , ..., f iuk . Aceast schem nu mai funcioneaz atunci cnd numrul de
descendeni ai unui nod este nemrginit, deoarece nu tim cte cmpuri (tablouri n reprezentarea
multi-tablou) s alocm n avans. Mai mult, chiar dac numrul k de descendeni este mrginit
de o constant mare, dar majoritatea nodurilor au un numr mic de descendeni, vom irosi mult
memorie.
Din fericire, exist o schem inteligent de a folosi arbori binari pentru a reprezenta arbori
cu numr arbitrar de descendeni. Ea are avantajul c utilizeaz un spaiu de O(n) pentru ori-
ce arbore cu rdcin i cu n noduri. Reprezentarea descendent-stng, frate-drept este
ilustrat n figura 11.10. Fiecare nod conine un pointer spre printe p, iar rdcin[T ] refer
rdcina arborelui T. n loc s avem un pointer spre fiecare descendent, fiecare nod x are doar
doi pointeri:

1. fiu-stng[x] refer cel mai din stnga descendent al nodului x i

2. frate-drept[x] refer fratele lui x, cel mai apropiat spre dreapta.

Dac nodul x nu are descendeni atunci fiu-stng[x] = nil, iar dac nodul x este cel mai din
dreapta descendent al printelui su atunci frate-drept[x] = nil.

Alte reprezentri ale arborilor


Uneori reprezentm arborii cu rdcin i n alte moduri. n capitolul 7, de exemplu, am
reprezentat un ansamblu, care se bazeaz pe un arbore binar complet, printr-un singur tablou
plus un indice. Arborii care apar n capitolul 22 sunt traversai numai spre rdcin, de aceea
doar pointerii spre prini sunt prezeni; nu exist pointeri spre descendeni. Sunt posibile i
multe alte scheme. Care este cea mai bun schem care depinde de aplicaie.

Exerciii
11.4-1 Desenai arborele binar avnd rdcina la indicele 6, care este reprezentat de urmtoarele
cmpuri.
184 Capitolul 11 Structuri de date elementare

Figura 11.10 Reprezentarea descendent-stng, frate-drept a unui arbore T. Fiecare nod x are cmpurile
p[x] (partea de sus), fiu-stng[x] (partea din stnga jos) i frate-drept[x] (partea din dreapta jos). Cheile
nu sunt ilustrate.
indice cheie stnga dreapta
1 12 7 3
2 15 8 nil
3 4 10 nil
4 10 5 9
5 2 nil nil
6 18 1 4
7 7 nil nil
8 14 6 2
9 21 nil nil
10 5 nil nil
11.4-2 Scriei o procedur recursiv cu timp de execuie O(n) care, fiind dat un arbore binar
cu n noduri, tiprete cheia fiecrui nod din arbore.
11.4-3 Scriei o procedur nerecursiv cu timp de execuie O(n) care, fiind dat un arbore binar
cu n noduri, tiprete cheia fiecrui nod din arbore. Folosii o stiv ca o structur auxiliar de
date.
11.4-4 Scriei o procedur cu timp de execuie O(n) care tiprete toate cheile unui arbore
arbitrar cu rdcin avnd n noduri, dac arborele este memorat folosind reprezentarea descen-
dent-stng, frate-drept.
11.4-5 ? Scriei o procedur nerecursiv cu timp de execuie O(n) care, fiind dat un arbore
binar cu n noduri, tiprete cheile fiecrui nod. Folosii numai un spaiu suplimentar constant
n afara arborelui nsui i nu modificai arborele, nici mcar temporar, n timpul procedurii.
11.4-6 ? Reprezentarea descendent-stng, frate-drept a unui arbore arbitrar cu rdcin
folosete trei pointeri n fiecare nod: fiu-stng, frate-drept i printe. Din fiecare nod se pot
atinge i identifica printele i toi descendenii nodului. Artai cum se poate obine acelai
efect, folosind doar doi pointeri i o valoare boolean n fiecare nod.
Probleme 185

Probleme
11-1 Comparaii ntre liste
Pentru fiecare din cele patru tipuri de liste din tabelul urmtor, care este timpul asimptotic
de execuie n cazul cel mai defavorabil pentru fiecare dintre operaiile pe mulimi dinamice
specificate n tabelul urmtor?
nesortat, sortat, nesortat, sortat,
simplu simplu dublu dublu
nlnuit nlnuit nlnuit nlnuit
Caut(L, k)
Insereaz(L, x)
terge(L, x)
Succesor(L, x)
Predecesor(L, x)
Minim(L)
Maxim(L)

11-2 Absambluri interclasate folosind liste nlnuite


Un ansamblu interclasat are urmtoarele operaii: Creeaz-Ansamblu (care creeaz un
ansamblu interclasat vid), Insereaz, Minim, Extrage-Min i Reunete. Artai cum se pot
implementa ansamblurile interclasate folosind liste nlnuite n fiecare din urmtoarele cazuri.
ncercai s realizai fiecare operaie ct mai eficient posibil. Analizai timpul de execuie n
termenii dimensiunii mulimii (mulimilor) dinamice cu care se opereaz. a. Listele sunt sortate.
b. Listele nu sunt sortate. c. Listele nu sunt sortate, iar mulimile dinamice ce se interclaseaz
sunt disjuncte.

11-3 Cutarea ntr-o list sortat compact


Exerciiul 11.3-4 cerea modul n care putem menine o list avnd n elemente, compact n
primele n poziii ale unui tablou. Vom presupune c toate cheile sunt distincte i c lista compact
este de asemenea sortat, adic, cheie[i] < cheie[urm[i]], oricare ar fi i = 1, 2, ..., n pentru care
urm[i] 6= nil. Cu aceste presupuneri ne ateptm ca urmtorul algoritm aleator s efectueze
cutarea n list ntr-un timp O(n).
List-Compact-Caut(L, k)
1: i cap[L]
2: n lung[L]
3: ct timp i 6= nil i cheie[i] k execut
4: j Random(1, n)
5: dac cheie[i] < cheie[j] i cheie[j] < k atunci
6: ij
7: i urm[i]
8: dac cheie[i] = k atunci
9: returneaz i
10: returneaz nil
186 Capitolul 11 Structuri de date elementare

Dac ignorm liniile 46 din procedur, atunci avem algoritmul uzual pentru cutarea ntr-
o list nlnuit sortat, n care indicele i refer pe rnd fiecare poziie din list. Liniile 46
ncearc s sar n avans la o poziie j aleas aleator. Un astfel de salt este benefic dac cheie[j]
este mai mare dect cheie[i] i mai mic dect k; ntr-un astfel de caz j marcheaz o poziie n
list prin care i va trebui s treac n timpul unei cutri obinuite n list. Deoarece lista este
compact, tim c orice alegere a lui j ntre 1 i n refer un obiect din list i nu o poziie n lista
liber.

a. De ce presupunem n List-Compact-Caut c toate cheile sunt distincte? Argumentai


c salturile aleatoare nu ajut neaprat n cazul asimptotic, dac lista conine dubluri ale
cheilor.

Performana procedurii List-Compact-Caut poate fi analizat mprind execuia sa


n dou faze. n timpul primei faze, ignorm orice avans realizat n determinarea lui k, ce se
realizeaz n liniile 79. Deci, faza 1 const doar n avansul n list prin salturi aleatoare. Asem-
ntor, faza 2 ignor avansul ce se realizeaz n liniile 46 i astfel va opera ca o cutare liniar
obinuit.
Fie Xt variabila aleatoare care descrie distana n lista nlnuit (i anume, prin nlnuirea
pointerilor urm) de la poziia i la cheia dorit k dup t iteraii ale fazei 1.

b. Argumentai c timpul de execuie dorit pentru List-Compact-Caut este O(t +


E[Xt ]), pentru orice t 0.
Pn
c. Artai c E[Xt ] r=1 (1 r/n)t . (Indicaie: Folosii relaia (6.28).)
Pn1
d. Artai c r=1 rt nt+1 /(t + 1).
e. Demonstrai c E[Xt ] n/(t + 1) i explicai de ce aceast formul este intuitiv.

f. Artai c List-Compact-Caut se execut ntr-un timp de O( n).

Note bibliografice
Aho, Hopcroft i Ullman [5] i Knuth [121] sunt referine excelente pentru structuri de date
elementare. Gonnet [90] furnizeaz date experimentale asupra performanelor operaiilor pentru
multe structuri de date.
Originea stivelor i cozilor ca structuri de date n informatic este neclar, deoarece noiunile
corespunztoare existau deja n matematic i n prelucrarea tradiional a documentelor nainte
de introducerea calculatoarelor digitale. Knuth [121] l citeaz pe A. M. Turing pentru folosirea
stivelor la legarea subrutinelor n 1947.
De asemenea, structurile de date bazate pe pointeri par a fi o invenie din folclor. Conform
lui Knuth, pointerii se pare c erau utilizai pe calculatoarele timpurii cu memorie pe tambur
magnetic. Limbajul A-1, dezvoltat de G. M. Hopper n 1951 reprezenta formulele algebrice ca
arbori binari. Knuth crediteaz limbajul IPL-II, dezvoltat n 1956 de A. Newell, J. C. Shaw
i H. A. Simon, cu recunoaterea importanei i promovarea utilizrii pointerilor. Limbajul lor
IPL-III, dezvoltat n 1957, include operaii explicite asupra stivelor.
12 Tabele de dispersie

Multe aplicaii necesit o mulime dinamic pentru care s se aplice numai operaiile specifice
pentru dicionare Insereaz, Caut i terge. De exemplu, un compilator pentru un limbaj
de programare ntreine o tabel de simboluri, n care cheile elementelor sunt iruri arbitrare
de caractere ce corespund identificatorilor din limbaj. O tabel de dispersie este o structur
eficient de date pentru implementarea dicionarelor. Dei cutarea unui element ntr-o tabel
de dispersie poate necesita la fel de mult timp ca i cutarea unui element ntr-o list nlnuit
un timp (n) n cazul cel mai defavorabil n practic, dispersia funcioneaz extrem de bine.
Pe baza unor ipoteze rezonabile, timpul preconizat pentru cutarea unui element ntr-o tabel
de dispersie este O(1).
O tabel de dispersie este o generalizare a noiunii mai simple de tablou. Adresarea direct
ntr-un tablou folosete abilitatea noastr de a examina o poziie arbitrar n tablou ntr-un
timp O(1). Seciunea 12.1 discut n detaliu despre adresarea direct. Adresarea direct este
aplicabil n cazul n care ne putem permite s alocm un tablou care are cte o poziie pentru
fiecare cheie posibil.
Cnd numrul cheilor memorate efectiv este relativ mic fa de numrul total de chei posibile,
tabelele de dispersie devin o alternativ eficient la adresarea direct ntr-un tablou, deoarece o
tabel de dispersie folosete n mod normal un tablou de mrime proporional cu numrul de
chei memorate efectiv. n loc s folosim direct cheia ca indice n tablou, indicele este calculat pe
baza cheii. n seciunea 12.2 sunt prezentate ideile principale, iar n seciunea 12.3 se descrie cum
pot fi calculai indicii din tablou pe baza cheilor, folosind funcii de dispersie. Sunt prezentate i
analizate diferite variaii ale temei de baz; ideea de baz este c dispersia reprezint o tehnic
extrem de eficient i practic; operaiile de baz pentru dicionare necesit, n medie, doar un
timp O(1).

12.1. Tabele cu adresare direct


Adresarea direct este o tehnic simpl care funcioneaz bine atunci cnd universul U al
cheilor este rezonabil de mic. S presupunem c o aplicaie necesit o mulime dinamic n care
fiecare element are o cheie aleas dintr-un univers U = {0, 1, ..., m 1}, unde m nu este foarte
mare. Vom presupune c nu exist dou elemente avnd aceeai cheie.
Pentru a reprezenta mulimea dinamic folosim un tablou sau o tabel cu adresare direct
T [0..m 1], n care fiecare poziie sau locaie corespunde unei chei din universul U. Figura 12.1
ilustreaz aceast abordare; locaia k refer elementul avnd cheia k din mulime. Dac mulimea
nu conine un element cu cheia k, atunci T [k] = nil.
Operaiile pentru dicionare sunt uor de implementat.
Adresare-Direct-Caut(T, k)
returneaz T [k]

Adresare-Direct-Insereaz(T, x)
T [cheie[x]] x
188 Capitolul 12 Tabele de dispersie

Figura 12.1 Implementarea unei mulimi dinamice printr-un tablou cu adresare direct T. Fiecare
cheie din universul U = {0, 1, ..., 9} corespunde unui indice n tablou. Mulimea K = {2, 3, 5, 8} a cheilor
efective determin locaiile din tablou care conin pointeri ctre elemente. Celelalte locaii, haurate mai
ntunecat, conin nil.

Adresare-Direct-terge(T, x)
T [cheie[x]] nil

Fiecare dintre aceste operaii este rapid: este necesar doar un timp O(1).
Pentru unele aplicaii, elementele din mulimea dinamic pot fi memorate chiar n tabela cu
adresare direct. Aceasta nseamn c n loc s memorm cheia elementului i datele adiionale
ntr-un obiect extern tabelei cu adresare direct, printr-un pointer dintr-o poziie din tabel ctre
obiect, putem s memorm obiectul n locaia respectiv, economisind astfel spaiu. Mai mult,
deseori nu este necesar s memorm cmpul cheie al obiectului, deoarece dac avem indicele
unui obiect n tabel avem i cheia sa. Oricum, dac cheile nu sunt memorate, trebuie s existe
o modalitate de a afirma c locaia este goal.

Exerciii
12.1-1 Se consider o mulime dinamic S care este reprezentat printr-o tabel T cu adresare
direct, de lungime m. Descriei o procedur care gsete elementul maxim din S. Care este
performana procedurii pentru cazul cel mai defavorabil?

12.1-2 Un vector de bii este un tablou simplu de bii (cu 0 i 1). Un vector de bii de
lungime m ocup mult mai puin spaiu dect un tablou de m pointeri. Descriei cum se poate
folosi un vector de bii pentru a reprezenta o mulime dinamic avnd elemente distincte, fr
date adiionale. Operaiile pentru dicionare ar trebui s funcioneze ntr-un timp O(1).

12.1-3 Sugerai cum se poate implementa o tabel cu adresare direct n care cheile elementelor
memorate nu sunt neaprat distincte i elementele pot avea date adiionale. Toate cele trei
operaii pentru dicionare (Insereaz, terge i Caut) ar trebui s se execute ntr-un timp
O(1). (Nu uitai c terge are ca argument un pointer la obiectul ce va fi ters i nu o cheie.)
12.2. Tabele de dispersie 189

Figura 12.2 Folosirea unei funcii de dispersie h pentru a transforma chei n poziii din tabela de
dispersie. Cheile k2 i k5 se transform n aceeai poziie, deci sunt n coliziune.

12.1-4 ? Dorim s implementm un dicionar folosind adresarea direct pe un tablou uria. La


nceput, intrrile n tablou pot conine date nesemnificative, iar iniializarea ntregului tablou
este nepractic datorit mrimii sale. Descriei o schem pentru implementarea unui dicionar cu
adresare direct printr-un tablou uria. Fiecare obiect memorat ar trebui s utilizeze un spaiu
O(1); operaiile Caut, Insereaz i terge ar trebui s funcioneze fiecare ntr-un timp
O(1); iniializarea structurii de date ar trebui s necesite un timp O(1). (Indicaie: Folosii o
stiv suplimentar, a crei mrime s fie numrul de chei efectiv memorate n dicionar, pentru
a determina dac o intrare dat n tabloul uria este valid sau nu.)

12.2. Tabele de dispersie


Dificultatea n adresarea direct este evident: dac universul U este mare, memorarea tabe-
lului T poate fi nepractic, sau chiar imposibil, dat fiind memoria disponibil a unui calculator
uzual. Mai mult, mulimea K a cheilor efectiv memorate poate fi att de mic relativ la U, nct
majoritatea spaiului alocat pentru T ar fi irosit.
Cnd mulimea K a cheilor memorate ntr-un dicionar este mult mai mic dect universul
U al cheilor posibile, o tabel de dispersie necesit un spaiu de memorie mult mai mic dect
o tabel cu adresare direct. Mai exact, cerinele de memorare pot fi reduse la (|K|), chiar i
atunci cnd cutarea unui element n tabela de dispersie necesit tot un timp O(1). (Singurul
punct slab este c aceast margine este stabilit pentru timpul mediu, n timp ce pentru adresarea
direct ea era valabil pentru cazul cel mai defavorabil.)
Prin adresare direct, un element avnd cheia k este memorat n locaia k. Prin dispersie,
acest element este memorat n locaia h(k); aceasta nseamn c o funcie de dispersie h este
folosit pentru a calcula locaia pe baza cheii k. n acest caz, h transform universul U al cheilor
n locaii ale unei tabele de dispersie T [0..m 1]:
h : U {0, 1, ..., m 1}.
Vom spune c un element cu cheia k se disperseaz n locaia h(k); de asemenea vom spune c
190 Capitolul 12 Tabele de dispersie

Figura 12.3 Rezolvarea coliziunii prin nlnuire. Fiecare locaie din tabela de dispersie T [j] conine
o list nluit a tuturor cheilor a cror valoare de dispersie este j. De exemplu, h(k1 ) = h(k4 ) i
h(k5 ) = h(k2 ) = h(k7 ).

h(k) este valoarea de dispersie a cheii k. Figura 12.2 ilustreaz ideea de baz. Scopul funciilor
de dispersie este de a reduce domeniul indicilor tabloului care trebuie manipulai. n loc de |U |
valori, va trebui s manipulm doar m valori. Cerinele de memorare sunt reduse corespunztor.

Dezavantajul acestei idei frumoase este c dou chei se pot dispersa n aceeai locaie, adic
se produce o coliziune. Din fericire, exist tehnici eficiente pentru rezolvarea conflictelor create
de coliziuni.
Desigur, soluia ideal ar fi s nu existe coliziuni. Putem ncerca s atingem acest scop printr-
o alegere potrivit a funciei de dispersie h. O idee este de a-l face pe h s par aleator, evitnd
astfel coliziunile sau cel puin minimiznd numrul lor. Termenul de dispersie, care evoc
imaginea unei frmiri i amestecri aleatoare, capteaz spiritul acestei abordri. (Bineneles,
o funcie de dispersie h trebuie s fie determinist, n sensul c o intrare dat k trebuie s produc
ntotdeauna aceeai ieire h(k).) Deoarece |U | > m, exist cu siguran dou chei care s aibe
aceeai valoare de dispersie; de aceea, evitarea total a coliziunilor este imposibil. Prin urmare,
dei o funcie de dispersie aleatoare, bine proiectat, poate minimiza numrul coliziunilor, avem
n continuare nevoie de o metod pentru rezolvarea coliziunilor ce apar.
Restul acestei seciuni prezint cea mai simpl tehnic de rezolvare a coliziunilor, numit
nlnuire. n seciunea 12.4 se introduce o metod alternativ de rezolvare a coliziunilor, numit
adresare deschis.

Rezolvarea coliziunii prin nlnuire


Prin nlnuire punem toate elementele ce se disperseaz n aceeai locaie, ntr-o list
nlnuit, dup cum se arat n figura 12.3. Locaia j conine un pointer ctre capul listei tu-
turor elementelor care se disperseaz n locaia j; dac nu exist astfel de elemente, locaia j
conine nil.
Operaiile pentru dicionare sunt uor de implementat pe o tabel de dispersie, n cazul n
care coliziunile sunt rezolvate prin nlnuire.
12.2. Tabele de dispersie 191

Dispersie-Cu-Inlnuire-Insereaz(T, x)
insereaz x n capul listei T [h(cheie[x])]

Dispersie-Cu-Inlnuire-Caut(T, k)
caut un element cu cheia k n lista T [h(k)]

Dispersie-Cu-Inlnuire-terge(T, x) indexDispersie-Cu-Inlantuire-Sterge@Dispersie-
Cu-Inlnuire-terge
terge x din lista T [h(cheie[x])]

Timpul de execuie pentru inserare n cazul cel mai defavorabil este O(1). Pentru cutare,
timpul de execuie n cazul cel mai defavorabil este proporional cu lungimea listei; vom analiza
ndeaproape aceast situaie n cele ce urmeaz. tergerea unui element x poate fi realizat ntr-
un timp O(1) dac listele sunt dublu nlnuite. (Dac listele sunt simplu nlnuite, atunci
trebuie nti s-l gsim pe x n lista T [h(cheie[x])], astfel nct legtura next a predecesorului lui
x s fie modificat corespunztor ca s-l ocoleasc pe x; n acest caz, tergerea i cutarea au
n esen acelai timp de execuie.)

Analiza dispersiei cu nlnuire


Ct de bine funcioneaz dispersia prin nlnuire? n particular, ct dureaz cutarea unui
element avnd o cheie dat?
Fiind dat o tabel de dispersie T cu m locaii ce memoreaz n elemente, vom defini factorul
de ncrcare pentru T prin n/m, raport care reprezint numrul mediu de elemente memorate
ntr-o nlnuire. Analiza noastr se bazeaz pe ; adic, ne imaginm ca fiind fix n timp ce
n i m tind la infinit. (Se observ c poate fi mai mic, egal sau mai mare dect 1.)
Comportamentul, n cazul cel mai defavorabil, al dispersiei prin nlnuire este slab: toate
cele n chei se disperseaz n aceeai locaie, crend o list de lungime n. Timpul de cutare pentru
cazul cel mai defavorabil este astfel (n) plus timpul pentru calculul funciei de dispersiecu
nimic mai bun dect n cazul n care am fi folosit o list nlnuit a tuturor elementelor. Este
clar c tabelele de dispersie nu sunt folosite pentru performana lor n cazul cel mai defavorabil.
Performana dispersiei n cazul mediu depinde de ct de bine distribuie (n medie) funcia de
dispersie h mulimea cheilor ce trebuie memorate n cele m locaii. n seciunea 12.3 se discut
aceste probleme, dar deocamdat vom presupune c orice element se poate dispersa n oricare
din cele m locaii cu aceeai probabilitate, independent de locul n care s-au dispersat celelalte
elemente. Vom numi aceast ipotez de lucru dispersie uniform simpl.
Presupunem c valoarea de dispersie h(k) poate fi calculat ntr-un timp O(1), astfel nct
timpul necesar pentru a cuta un element avnd cheia k depinde liniar de lungimea listei T [h(k)].
Lsnd de o parte timpul O(1) necesar pentru calculul funciei de dispersie i pentru accesul
la locaia h(k), s lum n considerare numrul mediu de elemente examinate de algoritmul de
cutare, adic, numrul de elemente din lista T [h(k)] care sunt verificate pentru a vedea dac
cheia lor este egal cu k. Vom considera dou cazuri. n primul caz, cutarea este fr succes:
nici un element din tabel nu are cheia k. n al doilea caz, cutarea gsete cu succes un element
avnd cheia k.
192 Capitolul 12 Tabele de dispersie

Teorema 12.1 ntr-o tabel de dispersie n care coliziunile sunt rezolvate prin nlnuire, o
cutare fr succes necesit, n medie, un timp (1 + ), n ipoteza dispersiei uniforme simple.

Demonstraie. n ipoteza dispersiei uniforme simple, orice cheie k se poate dispersa cu aceeai
probabilitate n oricare din cele m locaii. Astfel, timpul mediu pentru o cutare fr succes,
pentru o cheie k, este timpul mediu pentru cutarea pn la coada uneia din cele m liste. Deci,
numrul mediu de elemente examinate ntr-o cutare fr succes este i timpul total necesar
(incluznd timpul pentru calculul lui h(k)) este (1 + ).

Teorema 12.2 ntr-o tabel de dispersie n care coliziunile sunt rezolvate prin nlnuire, o
cutare cu succes necesit, n medie, un timp (1 + ), n ipoteza dispersiei uniforme simple.

Demonstraie. Presupunem c cheia care este cutat poate fi, cu aceeai probabilitate, oricare
din cele n chei memorate n tabel. De asemenea, presupunem c procedura Dispersie-Cu-
Inlnuire-Insereaz insereaz un nou element la sfritul unei liste i nu la nceputul ei.
(Conform exerciiului 12.2-3, timpul mediu pentru o cutare cu succes este acelai indiferent
dac noile elemente se insereaz la nceputul sau la sfritul listei.) Numrul mediu de elemente
examinate ntr-o cutare cu succes este cu 1 mai mare dect numrul de elemente examinate n
cazul n care elementul cutat a fost inserat (deoarece fiecare nou element se adaug la sfritul
listei). n concluzie, pentru a afla numrul mediu de elemente examinate, vom considera media
celor n obiecte din tabel, ca fiind 1 plus lungimea presupus a listei n care se adaug al i-lea
element. Lungimea medie a listei respective este (i 1)/m i deci, numrul mediu de elemente
examinate ntr-o cutare cu succes este:
n n
1X i1 1 X 1 (n 1)n 1
1+ =1+ (i 1) = 1 + =1+ .
n i=1 m nm i=1 nm 2 2 2m

Deci, timpul total necesar unei cutri cu succes (incluznd timpul pentru calculul funciei de
dispersie) este (2 + /2 1/2m) = (1 + ).
Ce semnificaie are aceast analiz? Dac numrul de locaii din tabela de dispersie este
cel puin proporional cu numrul de elemente din tabel, avem n = O(m) i, prin urmare,
= n/m = O(m)/m = O(1). Deci, cutarea necesit, n medie, un timp constant. Deoarece
inserarea necesit un timp O(1), n cazul cel mai defavorabil (vezi exerciiul 12.2-3) iar tergerea
necesit un timp O(1) n cazul cel mai defavorabil, cnd listele sunt dublu nlnuite, toate
operaiile pentru dicionare pot fi efectuate n medie ntr-un timp O(1).

Exerciii
12.2-1 Presupunnd c folosim o funcie de dispersie aleatoare h pentru a dispersa n chei
distincte ntr-un tablou T de dimensiune m, care este numrul mediu de coliziuni? Mai exact,
care este cardinalul probabil al mulimii {(x, y) : h(x) = h(y)}?

12.2-2 Ilustrai inserarea cheilor 5, 28, 19, 15, 20, 33, 12, 17, 10 ntr-o tabel de dispersie cu
coliziunile rezolvate prin nlnuire. Tabela are 9 locaii, iar funcia de dispersie este h(k) =
k mod 9.
12.3. Funcii de dispersie 193

12.2-3 Argumentai c timpul mediu pentru o cutare cu succes prin nlnuire este acelai
indiferent dac noile elemente se insereaz la nceputul, respectiv la sfritul unei liste. (Indicaie:
Artai c timpul mediu pentru o cutare cu succes este acelai pentru oricare dou ordine ale
unei liste.)

12.2-4 Profesorul Marley emite ipoteza c se poate mbunti esenial performana dac
modificm schema de nlnuire astfel nct fiecare list s fie pstrat ordonat. n ce mod
afecteaz modificarea profesorului timpul de execuie pentru cutari cu succes, cutri fr
succes, inserri i tergeri?

12.2-5 Sugerai cum poate fi alocat i dealocat spaiul de gestionare pentru elemente n cadrul
tabelei de dispersie prin legarea tuturor locaiilor nefolosite ntr-o list liber. Presupunem c o
locaie poate memora un indicator (engl. flag) mpreun cu un element i un pointer, sau cu
doi pointeri. Toate operaiile pentru dicionare pentru lista liber trebuie s funcioneze ntr-un
timp O(1). Este necesar ca lista liber s fie dublu nlnuit sau este suficient s fie simplu
nlnuit?

12.2-6 Artai c dac |U | > nm, exist o submulime a lui U de mrime n ce conine chei
care se disperseaz toate n aceeai locaie, astfel nct timpul de cutare, pentru dispersie cu
nlnuire, n cazul cel mai defavorabil, este (n).

12.3. Funcii de dispersie


n aceast seciune vom discuta unele aspecte legate de construirea de funcii de dispersie
bune, apoi vom prezenta trei scheme pentru crearea lor: dispersia prin diviziune, dispersia prin
nmulire i dispersia universal.

Ce nseamn o funcie de dispersie bun?


O funcie de dispersie bun satisface (aproximativ) ipoteza dispersiei uniforme simple: fiecare
cheie se poate dispersa cu aceeai probabilitate n oricare dintre cele m locaii. Mai formal, s
presupunem c fiecare cheie este aleas independent din U conform unei distribuii de probabi-
litate P ; dei, P (k) este probabilitatea de a fi aleas cheia k. Atunci ipoteza dispersiei uniforme
simple const n
X 1
P (k) = pentru j = 0, 1, ..., m 1 . (12.1)
m
k:h(k)=j

Din pcate, n general, nu este posibil verificarea acestei condiii, deoarece de regul
distribuia P nu este cunoscut.
Uneori (relativ rar) distribuia P este cunoscut. De exemplu, presupunem c se cunoate
faptul c cheile sunt numere reale aleatoare k, independent i uniform distribuite n intervalul
0 k < 1. n acest caz se poate arta c funcia de dispersie

h(k) = bkmc
194 Capitolul 12 Tabele de dispersie

satisface relaia (12.1).


n practic, se pot folosi tehnici euristice pentru a crea funcii de dispersie care par a se
comporta bine. Informaia calitativ despre P este uneori util n procesul de construcie al lor.
De exemplu, s considerm o tabel de simboluri a unui compilator, n care cheile sunt iruri
de caractere arbitrare, reprezentnd identificatori dintr-un program. O situaie des ntlnit este
aceea n care simboluri foarte asemntoare, ca pt i pts, apar n acelai program. O funcie de
dispersie bun va minimiza posibilitatea ca asemenea variaii s se disperseze n aceeai locaie.
O abordare uzual este de a obine valoarea de dispersie ntr-un mod care se vrea independent
de orice model sau ablon ce poate exista ntre date. De exemplu, metoda diviziunii (discutat
n detaliu mai jos) calculeaz valoarea de dispersie ca fiind restul mpririi cheii la un numr
prim specificat. n afara cazului n care numrul este ntr-un fel dependent de abloanele din
distribuia de probabilitate P , aceast metod d rezultate bune.
n final, s remarcm faptul c unele aplicaii ale funciilor de dispersie pot impune proprieti
mai tari dect cele asigurate de dispersia uniform simpl. De exemplu, am putea dori ca unele
chei care sunt apropiate ntr-un anumit sens s produc valori de dispersie care s fie total
diferite. (Aceast proprietate este dorit n special cnd folosim verificarea liniar, definit n
seciunea 12.4.)

Interpretarea cheilor ca numere naturale


Majoritatea funciilor de dispersie presupun universul cheilor din mulimea N = {0, 1, 2, ...}
a numerelor naturale. Astfel, dac cheile nu sunt numere naturale, trebuie gsit o modalitate
pentru a le interpreta ca numere naturale. De exemplu, o cheie care este un ir de caractere
poate fi interpretat ca un ntreg ntr-o baz de numeraie aleas convenabil. Prin urmare,
identificatorul pt poate fi interpretat ca o pereche de numere zecimale (112,116), pentru c p =
112 i t = 116 n mulimea codurilor ASCII; atunci pt exprimat ca un ntreg n baza 128 devine
(112 128)+116 = 14452. n mod obinuit, n orice aplicaie se poate crea direct o astfel de
metod simpl de a interpreta fiecare cheie ca un numr natural (posibil mare). n continuare,
vom presupune c avem chei numere naturale.

12.3.1. Metoda diviziunii


Prin metoda diviziunii pentru crearea funciilor de dispersie, transformm o cheie k ntr-
una din cele m locaii considernd restul mpririi lui k la m. Prin urmare, funcia de dispersie
este

h(k) = k mod m .

De exemplu, dac tabela de dispersie are dimensiunea m = 12 i cheia este k = 100, atunci
h(k) = 4. Deoarece necesit doar o singur operaie de mprire, dispersia prin diviziune este
rapid.
Cnd folosim metoda diviziunii, de obicei evitm anumite valori ale lui m. De exemplu, m
nu ar trebui s fie o putere a lui 2, pentru c dac m = 2p , atunci h(k) reprezint doar primii
p bii ai lui k. n afara cazului n care se cunoate apriori c distribuia de probabilitate pe
chei produce cu aceeai probabilitate oricare dintre abloanele primilor p bii, este mai bine s
construim funcia de dispersie ca dependent de toi biii cheii. Puterile lui 10 ar trebui evitate
dac aplicaia lucreaz cu numere zecimale ca i chei, pentru c n acest caz funcia de dispersie
12.3. Funcii de dispersie 195

Figura 12.4 Metoda nmulirii pentru dispersie. Reprezentarea pe w bii a cheii k este nmulit cu
valoarea pe w bii bA 2w c, unde 0 < A < 1 este o constant aleas convenabil. Primii p bii ai celei de
a doua jumti a produsului, de lungime w bii, formeaz valoarea de dispersie h(k) dorit.

nu depinde de toate cifrele zecimale ale lui k. n final, se poate arta c dac m = 2p 1 i k este
un ir de caractere interpretat n baza 2p , dou iruri de caractere care sunt identice, exceptnd
o transpoziie a dou caractere adiacente, se vor dispersa n aceeai valoare.
Valori bune pentru m sunt numerele prime nu prea apropiate de puterile exacte ale lui 2. De
exemplu, s presupunem c dorim s alocm o tabel de dispersie, cu coliziunile rezolvate prin
nlnuire, pentru a reine aproximativ n = 2000 iruri de caractere, unde un caracter are 8 bii.
Nu ne deranjeaz s examinm n medie 3 elemente ntr-o cutare fr succes, deci vom aloca
o tabel de dispersie de dimensiune m = 701. Numrul 701 este ales pentru c este un numr
prim apropiat de 2000/3, dar nu este apropiat de nici o putere a lui 2. Tratnd fiecare cheie k
ca un ntreg, funcia noastr de dispersie va fi

h(k) = k mod 701 .

Ca o msur de precauie, putem s verificm ct de uniform distribuie aceast funcie de


dispersie mulimi de chei n locaii, unde cheile sunt alese din date reale.

12.3.2. Metoda nmulirii


Metoda nmulirii pentru crearea de funcii de dispersie opereaz n doi pai. n primul pas,
nmulim cheia k cu o constant A din intervalul 0 < A < 1 i extragem partea fracionar a lui
kA. Apoi, nmulim aceast valoare cu m i considerm partea ntreag inferioar a rezultatului.
Pe scurt, funcia de dispersie este

h(k) = bm(kA mod 1)c ,

unde kA mod 1 nseamn partea fracionar a lui kA, adic, kA bkAc.


Un avantaj al metodei nmulirii este c valoarea lui m nu este critic. De obicei o alegem ca
fiind o putere a lui 2 m = 2p pentru un ntreg p pentru c atunci putem implementa funcia pe
majoritatea calculatoarelor dup cum urmeaz. S presupunem c lungimea cuvntului mainii
este de w bii i c k ncape pe un singur cuvnt. Referindu-ne la figura 12.4, nmulim nti
k cu ntregul pe w bii bA 2w c. Rezultatul este o valoare pe 2w bii r1 2w + r0 , unde r1 este
primul cuvnt al produsului i r0 este al doilea cuvnt al produsului. Valoarea de dispersie de p
bii dorit const din cei mai semnificativi p bii ai lui r0 .
196 Capitolul 12 Tabele de dispersie

Dei aceast metod funcioneaz cu orice valoare a constantei A, ea lucreaz mai bine cu
anumite valori dect cu altele. Alegerea optim depinde de caracteristicile datelor care sunt
dispersate. Knuth [123] discut alegerea lui A n detaliu i sugereaz c

A = ( 5 1)/2 0.6180339887... (12.2)

se va comporta relativ bine.


De exemplu, dac avem k = 123456, m = 10000 i A din relaia (12.2), atunci

h(k) = b10000 (123456 0.61803... mod 1)c = b10000 (76300.0041151... mod 1)c =
= b10000 0.0041151...c = b41.151...c = 41 .

12.3.3. Dispersia universal


Dac cheile ce se disperseaz sunt alese de un adversar maliios, atunci el poate alege n chei
care toate se vor dispersa n aceeai locaie, rezultnd un timp mediu de acces (n). n cazul cel
mai defavorabil, orice funcie de dispersie fixat este vulnerabil la acest tip de comportament;
singura modalitate eficient de a mbunti aceast situaie este de a alege funcia de dispersie
n mod aleator astfel nct alegerea s fie independent de cheile care se vor memora. Aceast
abordare, numit dispersie universal, produce n medie o performan bun, indiferent de
ce chei sunt alese de ctre adversar.
Ideea care st la baza dispersiei universale este de a selecta funcia de dispersie n mod
aleator n momentul execuiei dintr-o clas de funcii construit cu atenie. Ca i n cazul sortrii
rapide, randomizarea asigur c nici o intrare nu va produce comportamentul n cazul cel mai
defavorabil. Datorit randomizrii, algoritmul se poate comporta diferit la fiecare execuie, chiar
pentru o aceeai intrare. Aceast abordare asigur o performan bun pentru cazul mediu,
indiferent de cheile care sunt date ca intrare. Revenind la exemplul cu tabela de simboluri a unui
compilator, descoperim c alegerea identificatorilor de ctre programator nu poate cauza, din
punct de vedere al consistenei, performane slabe la dispersie. Performana slab apare doar
atunci cnd compilatorul alege o funcie de dispersie aleatoare care provoac o dispersie slab a
mulimii identificatorilor, dar probabilitatea ca aceast situaie s apar este mic i este aceeai
pentru orice mulime de identificatori de aceeai mrime.
Fie H o colecie finit de funcii de dispersie care transform un univers dat U al cheilor, n
domeniul {0, 1, ..., m1}. O astfel de colecie se numete universal dac pentru fiecare pereche
de chei distincte x, y U , numrul de funcii de dispersie h H pentru care h(x) = h(y) este
exact |H|/m. Cu alte cuvinte, cu o funcie de dispersie aleas aleator din H, ansa unei coliziuni
ntre x i y cnd x 6= y este exact 1/m, care este exact ansa unei coliziuni dac h(x) i h(y)
sunt alese aleator din mulimea {0, 1, ..., m 1}.
Urmtoarea teorem arat c o clas universal de funcii de dispersie d un comportament
bun n cazul mediu.

Teorema 12.3 Dac h este aleas dintr-o colecie universal de funcii de dispersie i este
folosit pentru a dispersa n chei ntr-o tabel de dimensiune m, unde n m, numrul mediu de
coliziuni n care este implicat o cheie particular x, este mai mic dect 1.

Demonstraie. Pentru fiecare pereche y, z de chei distincte, fie cyz variabila aleatoare care are
valoarea 1 dac h(y) = h(z) (adic, dac y i z sunt n coliziune folosind h) i 0 n caz contrar.
12.3. Funcii de dispersie 197

Deoarece, prin definiie, o singur pereche de chei sunt n coliziune cu probabilitatea 1/m, avem
E[cyz ] = 1/m .
Fie Cx numrul total de coliziuni n care este implicat cheia x dintr-o tabel de dispersie T
de dimensiune m coninnd n chei. Din relaia (6.24) obinem
X n1
E[Cx ] = E[cxy ] = .
m
yT
y6=x

Deoarece n m, obinem E[Cx ] < 1.


Dar ct de uor este s construim o clas universal de funcii de dispersie? Este relativ
uor, dup cum se poate demonstra folosind unele cunotine din teoria numerelor. S alegem
dimensiunea m a tabelei noastre ca fiind numr prim (ca i n metoda diviziunii). Descompunem
o cheie x n r + 1 octei (de exemplu, caractere sau subiruri binare de caractere de lungime fix),
astfel nct x = hx0 , x1 , ...xr i; singura cerin este ca valoarea maxim a unui octet s fie mai
mic dect m. Notm prin a = ha0 , a1 , ...ar i un ir de r + 1 elemente alese aleator din mulimea
{0, 1, ..., m 1}. Definim o funcie de dispersie corespunztoare ha H astfel:
r
X
ha (x) = ai xi mod m . (12.3)
i=0

Cu aceast definiie,
[
H = {ha }. (12.4)
a

are mr+1 elemente.

Teorema 12.4 Clasa H definit de relaiile (12.3) i (12.4) este o clas universal de funcii de
dispersie.

Demonstraie. Considerm o pereche oarecare de chei distincte x i y. Presupunem c x0 6= y0 .


(O argumentaie similar se poate face pentru diferena dintre oricare alte poziii ale octeilor.)
Pentru orice valori fixe ale lui a1 , a2 , ..., ar exist exact o valoare a lui a0 care satisface ecuaia
h(x) = h(y); acest a0 este soluia ecuaiei
r
X
a0 (x0 y0 ) ai (xi yi ) (mod m) .
i=1

Pentru a observa aceast proprietate s remarcm faptul c deoarece m este prim, cantitatea
nenul x0 y0 are un invers fa de nmulirea modulo m i astfel exist o soluie unic pentru
a0 modulo m. (Vezi seciunea 33.4.) Prin urmare, fiecare pereche de chei x i y este n coliziune
pentru exact mr valori ale lui a, deoarece ea este n coliziune exact o dat pentru fiecare valoare
posibil a lui ha1 , a2 , ..., ar i (de exemplu, pentru valoarea unic a lui a0 observat mai sus).
Deoarece exist mr+1 valori posibile pentru secvena a, cheile x i y sunt n coliziune exact cu
probabilitatea mr /mr+1 = 1/m. n concluzie, H este universal.
198 Capitolul 12 Tabele de dispersie

Exerciii
12.3-1 Presupunem c dorim s efectum o cutare ntr-o list nlnuit de lungime n, n care
fiecare element conine o cheie k mpreun cu o valoare de dispersie h(k). Fiecare cheie este un
ir lung de caractere. Cum putem profita de valorile de dispersie cnd cutm n list un element
cu o cheie dat?

12.3-2 Presupunem c un ir de r caractere este dispersat pe m poziii, fiind considerat ca


numr n baza 128, cruia i se aplic metoda diviziunii. Numrul m este uor de reprezentat
n memorie ca un cuvnt pe 32 de bii, dar irul de r caractere, tratat ca un numr n baza
128, necesit multe cuvinte. Cum putem aplica metoda diviziunii pentru a calcula valoarea de
dispersie a irului de caractere fr a folosi mai mult dect un numr suplimentar constant de
cuvinte de memorie n afar de irul propriu-zis?

12.3-3 Se consider o versiune a metodei diviziunii n care h(k) = k mod m, unde m = 2p 1


i k este un ir de caractere interpretat n baza 2p . Artai c dac irul de caractere x poate
fi obinut din irul de caractere y prin permutri de caractere, atunci x i y se disperseaz n
aceeai valoare. Dai un exemplu de aplicaie n care aceast proprietate nu este dorit pentru o
funcie de dispersie.

12.3-4 Se consider o tabel de dispersie


de dimensiune m = 1000 i funcia de dispersie
h(k) = bm(kA mod 1)c pentru A = ( 5 1)/2. Calculai locaiile n care se pun cheile 61, 62,
63, 64, i 65.

12.3-5 Artai c dac punem restricia ca fiecare component ai din a din relaia (12.3) s fie
nenul, atunci mulimea H = {ha } definit ca n relaia (12.4) nu este universal. (Indicaie: Se
consider cheile x = 0 i y = 1.)

12.4. Adresarea deschis


Prin adresare deschis, toate elementele sunt memorate n interiorul tabelei de dispersie.
Prin urmare, fiecare intrare n tabel conine fie un element al mulimii dinamice, fie nil. Cnd
cutm un element, vom examina sistematic locaiile tabelei fie pn cnd este gsit elementul
dorit, fie pn cnd este clar c elementul nu este n tabel. Nu exist liste sau elemente memorate
n afara tabelei, aa cum se ntmpl n cazul nlnuirii. Prin urmare, prin adresare deschis,
tabela de dispersie se poate umple astfel nct nici o inserare nu mai este posibil; factorul de
ncrcare nu poate depi niciodat valoarea 1.
Desigur, am putea memora listele nlnuite pentru a crea legturile n cadrul tabelei de
dispersie, n locaiile altfel neutilizate ale acesteia (vezi exerciiul 12.2-5), dar avantajul adresrii
deschise este c evit total folosirea pointerilor. Secvena de locaii care se examineaz nu se
determin folosind pointerii, ci se calculeaz. Spaiul de memorie suplimentar, eliberat prin faptul
c nu memorm pointerii, ofer tabelei de dispersie un numr mai mare de locaii pentru acelai
spaiu de memorie, putnd rezulta coliziuni mai puine i acces mai rapid.
Pentru a realiza inserarea folosind adresarea deschis, examinm succesiv sau verificm
tabela de dispersie pn cnd gsim o locaie liber n care s punem cheia. n loc s fie fixat
n ordinea 0, 1, ..., m 1 (care necesit un timp de cutare (n)), irul de poziii examinate
12.4. Adresarea deschis 199

depinde de cheia ce se insereaz. Pentru a determina ce locaii sunt verificate, extindem funcia
de dispersie astfel nct ea s includ i numrul de verificare (ncepnd de la 0) ca un al doilea
argument. Astfel, funcia de dispersie devine

h : U {0, 1, ..., m 1} {0, 1, ..., m 1} .

n cadrul adresrii deschise, cerem ca pentru fiecare cheie k, secvena de verificare

hh(k, 0), h(k, 1), ..., h(k, m 1)i

s fie o permutare a lui h0, 1, ..., m 1i, astfel nct fiecare poziie din tabela de dispersie s fie
considerat ca o eventual locaie pentru o nou cheie pe msur ce se umple tabela. n algoritmul
urmtor, presupunem c elementele din tabela de dispersie T sunt chei, fr informaii adiionale;
cheia k este identic cu elementul care conine cheia k. Fiecare locaie conine fie o cheie, fie nil
(dac locaia este liber).
Dispersie-Insereaz(T, k)
1: i 0
2: repet
3: j h(k, i)
4: dac T [j] = nil atunci
5: T [j] k
6: returneaz j
7: altfel
8: ii+1
9: pn cnd i = m
10: eroare depire tabela de dispersie

Algoritmul pentru cutarea unei chei k examineaz aceeai secven de locaii pe care o
folosete i algoritmul de inserare atunci cnd s-a inserat cheia k. Prin urmare, cutarea se poate
termina (fr succes) cnd se ntlnete o locaie liber, pentru c k ar fi fost inserat n acea
locaie i nu mai ncolo n secvena de verificare. (Se observ c aceast argumentaie presupune
c o dat introduse, cheile nu mai sunt terse din tabela de dispersie.) Procedura Dispersie-
Caut are ca intrare o tabel de dispersie T i o cheie k i returneaz j dac locaia j conine
cheia k sau nil dac cheia k nu exist n tabela T .
Dispersie-Caut(T, k)
1: i 0
2: repet
3: j h(k, i)
4: dac T [j] = k atunci
5: returneaz j
6: ii+1
7: pn cnd T [j] = nil sau i = m
8: returneaz nil

tergerea dintr-o tabel de dispersie cu adresare deschis este dificil. Cnd tergem o cheie
dintr-o locaie i, nu putem marca pur i simplu acea locaie ca fiind liber memornd n ea
200 Capitolul 12 Tabele de dispersie

valoarea nil. Procednd astfel, va fi imposibil s accesm orice cheie k a crei inserare a verificat
locaia i i a gsit-o ocupat. O soluie este de a marca locaia, memornd n ea valoarea special
ters n loc de nil. Apoi vom modifica procedura Dispersie-Insereaz astfel nct s trateze
astfel de locaii ca i cnd ar fi libere, astfel nct o nou cheie s poat fi inserat. Nu este
necesar nici o modificare n Dispersie-Caut, deoarece va trece peste valorile ters n timpul
cutrii. Procednd astfel, timpii de cutare nu mai depind de factorul de ncrcare i din
acest motiv n cazul n care cheile trebuie terse, se prefer, n mod uzual, nlnuirea ca tehnic
de rezolvare a coliziunilor.
n analiza noastr, folosim ipoteza dispersiei uniforme: presupunem c fiecare cheie
considerat poate avea, cu aceeai probabilitate, oricare dintre cele m! permutri ale mulimii
{0, 1, ..., m 1} ca secven de verificare. Dispersia uniform generalizeaz noiunea de dispersie
uniform simpl, definit anterior, pentru situaia n care funcia de dispersie produce nu doar
un singur numr, ci o ntreag secven de verificare. Oricum, dispersia uniform real este dificil
de implementat i n practic sunt folosite aproximri convenabile (ca dispersia dubl, definit
mai trziu).
n mod obinuit sunt utilizate trei tehnici pentru a calcula secvenele de verificare necesare
adresrii deschise: verificarea liniar, verificarea ptratic i dispersia dubl. Toate aceste tehnici
garanteaz c hh(k, 0), h(k, 1), ..., h(k, m1)i este o permutare a lui h0, 1, ..., m1i pentru fiecare
cheie k. Nici una din aceste tehnici nu satisface condiia dispersiei uniforme, pentru c nici una
dintre ele nu e capabil s genereze mai mult de m2 secvene de verificare diferite (n loc de m!
ct cere dispersia uniform). Dispersia dubl are cel mai mare numr de secvene de verificare
i, dup cum era de ateptat, d cele mai bune rezultate.

Verificarea liniar
Fiind dat o funcie de dispersie ordinar h0 : U {0, 1, ..., m 1}, metoda verificrii
liniare folosete funcia de dispersie

h(k, i) = (h0 (k) + i) mod m

pentru i = 0, 1, ..., m 1. Fiind dat o cheie k, prima locaie examinat (verificat) este T [h0 (k)].
Apoi examinm locaia T [h0 (k) + 1] i aa mai departe pn la locaia T [m 1]. Apoi continum
circular cu locaiile T [0], T [1], ..., pn cnd, n final, verificm locaia T [h0 (k) 1]. Deoarece
poziia de start a verificrii determin ntreaga secven de verificare liniar, prin care sunt
folosite doar m secvene de verificri distincte.
Verificarea liniar este uor de implementat, dar apare o problem cunoscut sub numele
de grupare primar. n acest caz se formeaz iruri lungi de locaii ocupate, crescnd timpul
mediu de cutare. De exemplu, dac avem n = m/2 chei ntr-o tabel, n care fiecare locaie de
indice par este ocupat i fiecare locaie de indice impar este liber, atunci cutarea fr succes
necesit, 1,5 verificri n cazul mediu. Dac primele n = m/2 locaii sunt cele ocupate, numrul
mediu de verificri crete la aproximativ n/4 = m/8. Gruprile au probabilitate mare de apariie,
pentru c dac o locaie liber este precedat de i locaii ocupate, atunci probabilitatea ca locaia
liber s fie urmtoarea completat este (i + 1)/m, comparativ cu probabilitatea de 1/m pentru
cazul n care locaia precedent ar fi fost liber. Prin urmare, irurile de locaii ocupate tind s
se lungeasc i verificarea liniar nu este o aproximare foarte bun a dispersiei uniforme.
12.4. Adresarea deschis 201

Verificarea ptratic
Verificarea ptratic folosete o funcie de dispersie de forma
h(k, i) = (h0 (k) + c1 i + c2 i2 ) mod m , (12.5)
unde (ca i n cazul verificrii liniare) h0 este o funcie de dispersie auxiliar, c1 i c2 6= 0
sunt constante auxiliare i i = 0, 1, ..., m 1. Poziia verificat iniial este T [h0 (k)]; urmtoarele
poziii examinate sunt decalate cu cantiti ce depind ntr-o manier ptratic de numrul de
verificare i. Aceast metod lucreaz mult mai bine dect verificarea liniar, dar pentru a folosi
integral tabela de dispersie valorile lui c1 , c2 i m trebuie determinate corespunztor. Problema
12-4 ilustreaz o modalitate de determinare a acestor parametri. De asemenea, dac dou chei
au aceeai poziie de start a verificrii, atunci secvenele lor de verificare coincid, pentru c
h(k1 , 0 = h(k2 , 0) implic h(k1 , i) = h(k2 , i). Aceast situaie conduce la o form mai uoar
de grupare, numit grupare secundar. Ca i n cazul verificrii liniare, verificarea iniial
determin ntreaga secven, deci sunt folosite doar m secvene de verificare distincte.

Dispersia dubl
dispersia dubl este una dintre cele mai bune metode disponibile pentru adresarea deschis,
deoarece permutrile produse au multe din caracteristicile permutrilor alese aleator. dispersia
dubl folosete o funcie de dispersie de forma
h(k, i) = (h1 (k) + ih2 (k)) mod m ,
unde h1 i h2 sunt funcii de dispersie auxiliare. Poziia examinat iniial este T [h1 (k)]; poziiile
succesive de verificare sunt decalate fa de poziiile anterioare cu h2 (k) modulo m. Astfel,
contrar situaiei de verificarea liniar sau ptratic, n acest caz secvena de verificare depinde
n dou moduri de cheia k, pentru c fie poziia iniial de verificare, fie decalajul, fie amndou
pot varia. Figura 12.5 ilustreaz un exemplu de inserare prin dispersie dubl.
Valoarea h2 (k) i dimensiunea tabelei de dispersie m trebuie s fie prime ntre ele pentru
a fi parcurs ntreaga tabel de dispersie. n caz contrar, dac m i h2 (k) au un cel mai mare
divizor comun d > 1 pentru o cheie k, atunci o cutare pentru cheia k va examina doar a (1/d)-a
parte din tabela de dispersie. (Vezi capitolul 33.) O modalitate convenabil de a asigura aceast
condiie este de a avea un numr m ca o putere a lui 2 i de a construi h2 astfel nct s produc
ntotdeauna un numr impar. O alt modalitate este de a avea m prim i de a construi h2 astfel
nct s returneze ntotdeauna un ntreg pozitiv mai mic dect m. De exemplu, putem alege m
prim i
h1 (k) = k mod m ,
h2 (k) = 1 + (k mod m0 ) ,
unde m0 este ales s fie un pic mai mic dect m (s zicem m 1 sau m 2). De exemplu, dac
k = 123456, m = 701 i m0 = 700, avem h1 (k) = 80 i h2 (k) = 257, deci prima verificare se afl
la poziia 80 i fiecare a 257-a locaie (modulo m) este examinat pn cnd cheia este gsit
sau a fost examinat toat tabela.
dispersia dubl reprezint o mbuntire fa de verificarea liniar sau ptratic n sensul
c sunt folosite (m2 ) secvene de verificare, fa de (m), pentru c fiecare pereche posibil
(h1 (k), h2 (k)) produce o secven de verificare distinct c si cnd cheia variaz, poziia iniial
202 Capitolul 12 Tabele de dispersie

Figura 12.5 Inserarea prin dispersie dubl. Avem o tabel de dispersie de dimensiune 13, cu h1 (k) =
k mod 13 i h2 (k) = 1 + (k mod 11). Deoarece 14 1 mod 13 i 14 3 mod 11, cheia 14 va fi inserat
n locaia liber 9, dup ce locaiile 1 i 5 au fost examinate i gsite ca fiind deja ocupate.

a verificrii h1 (k) i decalajul h2 (k) pot varia independent. Ca rezultat, performana dispersiei
duble apare ca fiind foarte apropiat de performana schemei ideale a dispersiei uniforme.

Analiza dispersiei cu adresare deschis


Analiza noastr pentru adresarea deschis, este, ca i analiza pentru nlnuire, exprimat
n termenii factorului de ncrcare al tabelei de dispersie, cnd n i m tind spre infinit. S
reamintim c dac sunt memorate n elemente ntr-o tabel cu m locaii, numrul mediu de
elemente pe locaie este = n/m. Desigur, prin adresare deschis, avem cel mult un element
ntr-o locaie i, prin urmare, n m, ceea ce implic 1.
Presupunem c este folosit dispersia uniform. n aceast schem idealizat, secvena de
verificare hh(k, 0), h(k, 1), ..., h(k, m 1)i pentru orice cheie k poate s apar sub forma oricrei
permutri a mulimii h0, 1, ..., m 1i. Aceasta nseamn c fiecare secven de verificare posibil
poate fi folosit ca secven de verificare pentru o inserare sau o cutare. Desigur, o cheie dat
are o secven de verificare unic, fix, asociat ei; considernd distribuia de probabilitate pe
spaiul cheilor i operaia funciei de dispersie pe chei, fiecare secven de verificare posibil are
aceeai probabilitate de apariie.
Analizm acum numrul mediu de verificri pentru dispersia cu adresare deschis, n ipoteza
dispersiei uniforme i ncepem cu o analiz a numrului de verificri ce apar ntr-o cutare fr
succes.

Teorema 12.5 Fiind dat o tabel de dispersie cu adresare deschis cu factorul de ncrcare
= n/m < 1, n ipoteza dispersiei uniforme, numrul mediu de verificri dintr-o cutare fr
succes este cel mult 1/(1 ).

Demonstraie. ntr-o cutare fr succes, fiecare verificare, cu excepia ultimei, acceseaz o


12.4. Adresarea deschis 203

locaie ocupat care nu conine cheia dorit, iar ultima locaie examinat este liber. Definim
pi = Pr { exact i verificri acceseaz locaiile ocupate }
pentru i = 0, 1, 2, .... Pentru i > n, avem pi = 0, pentru c putem gsi cel mult n locaii deja
ocupate. Astfel, numrul mediu de verificri este

X
1+ ipi (12.6)
i=1

Pentru a evalua relaia (12.6), definim


qi = Pr { cel puin i verificri acceseaz locaiile ocupate }
pentru i = 0, 1, 2, .... Apoi putem folosi identitatea (6.28):

X
X
ipi = qi .
i=1 i=1

Care este valoarea lui qi pentru i 1? Probabilitatea ca prima verificare s acceseze o locaie
ocupat este n/m; prin urmare,
n
q1 = .
m
Prin dispersie uniform, a doua verificare, n cazul n care este necesar, va fi la una din cele
m 1 locaii rmase neverificate, din care n 1 sunt ocupate. Facem a doua verificare doar dac
prima verificare acceseaz o locaie ocupat; prin urmare,
n n 1
q2 = .
m m1

n general, a i-a verificare este necesar doar dac primele i 1 verificri acceseaz locaii
ocupate i locaia examinat este cu aceeai probabilitate oricare dintre cele m i + 1 locaii
rmase, din care n i + 1 sunt ocupate. Deci,
n n 1 n i + 1 n i
qi = ... = i
m m1 mi+1 m
pentru i = 1, 2, ..., n, pentru c (n j)/(m j) n/m dac n m i j 0. Dup n verificri,
toate cele n locaii ocupate au fost vizitate i nu vor fi verificate din nou i astfel qi = 0 pentru
i > n.
Acum se poate evalua relaia (12.6). Presupunnd < 1, numrul mediu de verificri ntr-o
cutare fr succes este

X
X 1
1+ ipi = 1 + qi 1 + + 2 + 3 + ... = . (12.7)
i=0 i=1
1

Relaia (12.7) are o interpretare intuitiv: prima verificare se face ntotdeauna, a doua
verificare este necesar cu o probabilitate aproximativ egal cu , a treia verificare este necesar
cu o probabilitate aproximativ egal cu 2 i aa mai departe.
204 Capitolul 12 Tabele de dispersie

Dac este o constant, teorema 12.5 prognozeaz faptul c o cutare fr succes necesit
un timp O(1). De exemplu, dac tabela de dispersie este pe jumtate plin, numrul mediu de
verificri ntr-o cutare fr succes este cel mult 1/(1 .5) = 2. Dac este 90% ocupat, numrul
mediu de verificri este cel mult 1/(1 .9) = 10.
Teorema 12.5 ne d, aproape imediat, performana procedurii Dispersie-Insereaz.

Corolarul 12.6 Inserarea unui element ntr-o tabel de dispersie cu adresare deschis, cu
factorul de ncrcare necesit , n cazul mediu, cel mult 1/(1) verificri, n ipoteza dispersiei
uniforme.

Demonstraie. Un element este inserat doar dac exist spaiu n tabel i, deci, < 1.
Inserarea unei chei necesit o cutare fr succes, urmat de o plasare a cheii n prima locaie
gsit liber. Prin urmare, numrul mediu de verificri este cel mult 1/(1 ).
Calculul numrului mediu de verificri pentru o cutare cu succes necesit un pic mai mult
de lucru.

Teorema 12.7 Fiind dat o tabel de dispersie cu adresare deschis, cu factorul de ncrcare
< 1, numrul mediu de verificri ntr-o cutare cu succes este cel mult
1 1
ln ,
1
n ipoteza dispersiei uniforme i presupunnd c fiecare cheie din tabel este cutat cu aceeai
probabilitate.

Demonstraie. O cutare pentru o cheie k urmeaz aceeai secven de verificare ce a fost


urmat cnd elementul avnd cheia k a fost inserat. Conform corolarului 12.6, dac k a fost a
i + 1-a cheie inserat n tabela de dispersie, numrul mediu de verificri fcute ntr-o cutare a
lui k este cel mult 1/(1 i/m) = m(m i). Calculnd media peste toate cele n chei din tabela
de dispersie, obinem numrul mediu de verificri dintr-o cutare cu succes:
n1 n1
1X m mX 1 1
= = (Hm Hmn ) ,
n i=0 m i n i=0 m i
Pi
unde Hi = j=1 1/j este al i-lea numr armonic (definit ca n relaia (3.5)). Folosind marginile
ln i Hi ln i + 1 din relaiile (3.11) i (3.12), obinem
m
X Z m
1 1 1
(Hm Hmn ) = 1/k (1/x)dx
mn
k=mn+1
1 1
= ln(m/(m n)) = ln(1/(1 ))

ca mrginire pentru numrul mediu de verificri ntr-o cutare cu succes.
Dac tabela de dispersie este pe jumtate ocupat, numrul mediu de verificri ntr-o cutare
cu succes este mai mic dect 1,387. Dac tabela de dispersie este 90% ocupat, numrul mediu
de verificri este mai mic dect 2,559.
Probleme 205

Exerciii
12.4-1 Se consider c se insereaz cheile 10, 22, 31, 4, 15, 28, 17, 88, 59 ntr-o tabel de dispersie
de lungime m = 11 folosind adresarea deschis cu funcia primar de dispersie h0 (k) = k mod m.
Ilustrai rezultatul inserrii acestor chei folosind verificarea liniar, verificarea ptratic cu c1 = 1
i c2 = 3 i folosind dispersia dubl cu h2 (k) = 1 + (k mod (m 1)).
12.4-2 Scriei un algoritm n pseudocod pentru Dispersie-terge dup descrierea din text
i modificai Dispersie-Insereaz i Dispersie-Caut pentru a ncorpora valoarea special
ters.
12.4-3 ? S presupunem c folosim dispersia dubl pentru a rezolva coliziunile; mai exact,
folosim funcia de dispersie h(k, i) = (h1 (k) + ih2 (k)) mod m. Artai c secvena de verificare
hh(k, 0), h(k, 1), ..., h(k, m 1)i este o permutare a secvenei de locaii h0, 1, ..., m 1i dac i
numai dac h2 (k) este relativ prim cu m. (Indicaie: Vezi capitolul 33.)
12.4-4 Se consider o tabel de dispersie cu adresare deschis i cu dispersie uniform i factorul
de ncrcare = 1/2. Dai margini superioare pentru numrul mediu de verificri ntr-o cutare
fr succes i pentru numrul mediu de verificri ntr-o cutare cu succes. Care este numrul
mediu de verificri ntr-o cutare cu succes? Repetai calculele pentru factorii de ncrcare 3/4
i 7/8.
12.4-5 ? S presupunem c inserm n chei ntr-o tabel de dispersie de dimensiune m folosind
adresarea deschis i dispersia uniform. Notm cup(n, m) probabilitatea de a nu apare nici
n(n1)/2m
o coliziune. Artai c p(n,
m) e . (Indicaie: Vezi relaia (2.7).) Argumentai c
atunci cnd n depete m, probabilitatea evitrii coliziunilor descrete rapid ctre zero.
12.4-6 ? Se consider o tabel de dispersie cu adresare deschis avnd factorul de ncrcare .
Determinai acea valoare nenul a lui pentru care numrul mediu de verificri ntr-o cutare
fr succes este de dou ori mai mare dect numrul mediu de verificri dintr-o cutare cu
succes. Folosii estimarea (1/)ln(1/(1 )) pentru numrul de verificri necesare ntr-o cutare
cu succes.

Probleme
12-1 Marginea celei mai lungi verificri pentru dispersie
O tabel de dispersie de dimensiune m este folosit pentru a memora n obiecte, cu n m/2.
Pentru rezolvarea coliziunilor se folosete adresarea deschis.
a. n ipoteza dispersiei uniforme, artai c pentru i = 1, 2, ..., n, probabilitatea ca a i-a
inserare s necesite strict mai mult de k verificri este cel mult 2k .
b. Artai c pentru i = 1, 2, ..., n, probabilitatea ca a i-a inserare s necesite mai mult de
2 lg n verificri este cel mult 1/n2 .
Fie variabila aleatoare Xi , semnificnd numrul de verificri necesare pentru a i-a inserare.
Ai artat la punctul (b) c Pr{Xi > 2 lg n} 1/n2 . Fie variabila aleatoare X = max1in Xi
care semnific numrul maxim de verificri necesare oricreia din cele n inserri.
206 Capitolul 12 Tabele de dispersie

c. Artai c Pr{X > 2 lg n} 1/n.

d. Artai c lungimea medie a celei mai lungi secvene de verificare este E[X] = O(lg n).

12-2 Cutarea ntr-o mulime static


Se cere s se implementeze o mulime dinamic avnd n elemente, n care cheile sunt numere.
Mulimea este static (nu exist operaiile Insereaz i terge) i singura operaie necesar
este Caut. Se pune la dispoziie un timp arbitrar pentru a preprocesa cele n elemente, astfel
nct operaiile de cutare s se execute rapid.

a. Artai c procedura Caut poate fi implementat astfel nct, n cazul cel mai defavorabil
s se execute ntr-un timp O(lg n), fr a folosi spaiu suplimentar fa de cel necesar
memorrii elementelor.

b. Se consider implementarea mulimii printr-o tabel de dispersie cu adresare deschis avnd


m locaii care folosete dispersia uniform. Care este spaiul minim necesar (de lungime
m n) suplimentar pentru ca performana, n cazul mediu a unei cutri fr succes, s fie
cel puin la fel de bun ca marginea de la punctul (a)? Rspunsul trebuie s fie o mrginire
asimptotic a lui m n n funcie de n.

12-3 Margini pentru mrimea locaiei la nlnuire


S presupunem c avem o tabel de dispersie cu n locaii, avnd coliziuni rezolvate prin nlnuire
i s presupunem c se insereaz n chei n tabel. Fiecare cheie se poate dispersa, cu aceeai
probabilitate, n oricare dintre locaii. Fie M numrul maxim de chei ntr-o locaie, dup ce toate
cheile au fost inserate. Demonstrai c E[M ], valoarea medie a lui M , are o margine superioar
egal cu O(lg n/ lg lg n).

a. Fie Qk probabilitatea ca un numr de k chei s se disperseze ntr-o locaie particular.


Argumentai c probabilitatea Qk este dat de
k nk
1 1 n
Qk = 1 .
n n k

b. Fie Pk probabilitatea ca M = k, adic probabilitatea ca locaia care conine cele mai multe
chei s conin k chei. Artai c Pk nQk .

c. Folosii aproximarea Stirling, din relaia (2.11), pentru a arta c Qk < ek /k k .

d. Artai c exist o constant c > 1 astfel nct Qk0 < 1/n3 pentru k0 = c lg n/ lg lg n.
Deducei c Pk < 1/n2 pentru k = c lg n/ lg lg n.

e. Artai c

c lg n c lg n c lg n
E[M ] Pr M> n + Pr M .
lg lg n lg lg n lg lg n

Deducei c E[M ] = O(lg n/ lg lg n).


Note bibliografice 207

12-4 Verificarea ptratic


S presupunem c avem o cheie k, care trebuie cutat ntr-o tabel de dispersie avnd poziiile
0, 1, ..., m 1 i s presupunem c avem o funcie de dispersie h care transform spaiul cheilor
n mulimea {0, 1, ..., m 1}. Schema de cutare este urmtoarea.

1. Se calculeaz valoarea i h(k) i se iniializeaz j 0.


2. Se verific poziia i pentru cheia dorit k. Dac se gsete sau dac poziia este liber
atunci cutarea se termin.
3. Se fac atribuirile j (i + j) mod m i se revine la pasul 2.

Se presupune c m este o putere a lui 2.

a. Artai c aceast schem este o instaniere a schemei generale de verificare ptratic


evideniind valorile specifice ale constantelor c1 i c2 din relaia (12.5).
b. Demonstrai c acest algoritm examineaz fiecare poziie din tabel n cazul cel mai
defavorabil.

12-5 dispersie k-universal


Fie H = {h} o clas de funcii de dispersie n care fiecare h transform universul U al
cheilor n {0, 1, ..., m 1}. Spunem c H este k-universal dac pentru fiecare secven fix
de k chei distincte hx1 , x2 , ..., xk i i pentru fiecare funcie h aleas aleator din H, secvena
hh(x1 ), h(x2 ), ..., h(xk )i este, cu aceeai probabilitate, oricare dintre cele mk secvene de lungime
k avnd elemente din {0, 1, ..., m 1}.

a. Artai c dac H este 2-universal atunci ea este universal.


b. Artai c clasa H definit n seciunea 12.3.3 nu este 2-universal.

c. Artai c dac modificm definiia lui H din seciunea 12.3.3 astfel nct fiecare funcie
s conin un termen constant b, adic dac nlocuim h(x) cu
r
X
ha,b (x) = ai xi + b mod m ,
i=0

atunci H este 2-universal.

Note bibliografice
Knuth [123] i Gonnet [90] sunt referine excelente pentru algoritmi de dispersie. Knuth
l crediteaz pe H. P. Luhn (1953) cu inventarea tabelelor de dispersie, mpreun cu metoda
nlnuirii pentru rezolvarea coliziunilor. Aproximativ n aceeai perioad, G. M. Amdahl a avut
ideea original a adresrii deschise.
13 Arbori binari de cutare

Arborii de cutare sunt structuri de date ce posed multe operaii specifice mulimilor di-
namice, ntre care menionm Caut, Minim, Maxim, Predecesor, Succesor, Insereaz i
terge. Prin urmare un arbore de cutare se poate folosi att ca dicionar, ct i pe post de
coad cu prioriti.
Operaiile de baz pe arborii binari consum un timp proporional cu nlimea arborelui.
Pentru un arbore binar complet cu n noduri, aceste operaii se execut n cazul cel mai defavorabil
ntr-un timp (lg n). Dac ns arborele este un lan liniar de n noduri, atunci timpul consumat
n cazul cel mai defavorabil este (n). n seciunea 13.4 vom vedea c nlimea unui arbore
binar de cutare construit aleator este O(lg n), deci operaiile de baz pe mulimile dinamice vor
consuma un timp de (lg n).
n practic nu se poate garanta c arborii binari de cutare se construiesc aleator, ns exist
diverse tipuri speciale de astfel de structuri de date pentru care se garanteaz performane bune
ale operaiilor de baz chiar i n cazurile cele mai defavorabile. Astfel, n capitolul 14 se prezint
un astfel de caz special, arborii rou-negru, care au nlimea O(lg n). Capitolul 19 introduce B-
arborii, care se folosesc n special la ntreinerea bazelor de date cu acces direct, memorate pe
suport magnetic extern.
Dup prezentarea proprietilor de baz ale arborilor binari de cutare, seciunile urmtoare
vor ilustra cum se traverseaz un astfel de arbore n scopul listrii valorilor sale n ordine
cresctoare, cum se caut o valoare memorat n arborele binar de cutare, cum se gsete
elementul minim sau maxim, cum se determin succesorul sau predecesorul unui element i cum
se insereaz (adaug) sau se terge un element. Proprietile matematice de baz ale arborilor
au fost prezentate n capitolul 5.

13.1. Ce este un arbore binar de cutare?


Aa cum sugereaz numele su, un arbore binar de cutare este organizat sub form de
arbore binar, aa cum se observ n figura 13.1. Un astfel de arbore se poate reprezenta printr-o
structur de date nlnuit, n care fiecare nod este un obiect. Pe lng un cmp cheie i date
adiionale, fiecare obiect nod conine cmpurile stnga, dreapta i p care puncteaz spre (refer)
nodurile corespunztoare fiului stng, fiului drept i respectiv printelui nodului. Dac un fiu
sau un printe lipsete, cmpul corespunztor acestuia va conine valoarea nil. Nodul rdcin
este singurul nod din arbore care are valoarea nil pentru cmpul printe p.
ntr-un arbore binar de cutare, cheile sunt ntotdeauna astfel memorate nct ele satisfac
proprietatea arborelui binar de cutare:

Fie x un nod dintr-un arbore binar de cutare. Dac y este un nod din subarborele
stng al lui x, atunci cheie[y] cheie[x]. Dac y este un nod din subarborele drept
al lui x, atunci cheie[x] cheie[y].

Astfel, n figura 13.1(a) cheia rdcinii este 5, iar cheile 2, 3 i 5 din subarborele stng nu sunt
mai mari dect 5, pe cnd cheile 7 i 8 din subarborele drept nu sunt mai mici dect 5. Aceeai
13.1. Ce este un arbore binar de cutare? 209

Figura 13.1 Arbori binari de cutare. Pentru orice nod x, cheile din subarborele stng al lui x au
valoarea mai mic sau egal cu cheie[x], iar cheile din subarborele drept al lui x au valoarea mai mare
sau egal cu cheie[x]. Aceeai mulime de valori se poate reprezenta prin arbori binari de cutare, diferii.
Timpul de execuie, n cazul cel mai defavorabil, pentru majoritatea operaiilor arborilor de cutare este
proporional cu nlimea arborelui. (a) Un arbore binar de cutare cu 6 noduri i de nlime 2. (b) Un
arbore binar de cutare mai puin eficient care conine aceleai chei i are nlimea 4.

proprietate se verific pentru fiecare nod din arbore. De exemplu, cheia 3 din figura 13.1(a) nu
este mai mic dect cheia 2 din subarborele su stng i nu este mai mare dect cheia 5 din
subarborele su drept.
Proprietatea arborelui binar de cutare ne permite s tiprim toate cheile n ordine cresc-
toare cu ajutorul unui algoritm recursiv simplu, numit traversarea arborelui n inordine.
Numele acestui algoritm deriv din faptul c cheia rdcinii unui subarbore se tiprete ntre
valorile din subarborele su stng i cele din subarborele su drept. (Similar, o traversare a
arborelui n preordine va tipri cheia rdcinii naintea cheilor din subarbori, iar o traversare
a arborelui n postordine va tipri cheia rdcinii dup cheile din subarbori). Pentru a folosi
procedura urmtoare n scopul tipririi tuturor elementelor din arborele binar de cutare T o
vom apela cu Arbore-Traversare-Inordine(rdcin[T ]).

Arbore-Traversare-Inordine(x)
1: dac x 6= nil atunci
2: Arbore-Traversare-Inordine(stnga[x])
3: afieaz cheie[x]
4: Arbore-Traversare-Inordine(dreapta[x])

Spre exemplu, traversarea n inordine a arborelui afieaz cheile fiecruia dintre arborii binari
de cutare din figura 13.1 n ordinea 2, 3, 5, 5, 7, 8. Corectitudinea algoritmului se demonstreaz
prin inducie folosind direct proprietatea arborelui binar de cutare. Deoarece dup apelul iniial
procedura se apeleaz recursiv de exact dou ori pentru fiecare nod din arbore o dat pentru
fiul su stng i nc o dat pentru fiul su drept rezult c este nevoie de un timp (n) pentru
a traversa un arbore binar de cutare cu n noduri.
210 Capitolul 13 Arbori binari de cutare

Exerciii
13.1-1 Desenai arbori binari de cutare de nlime 2, 3, 4, 5 i respectiv 6 pentru mulimea
de chei {1, 4, 5, 10, 16, 17, 21}.

13.1-2 Care este deosebirea dintre proprietatea arborelui binar de cutare i proprietatea de
ansamblu (heap) (7.1)? Se poate folosi proprietatea de ansamblu pentru a afia cheile unui arbore
avnd n noduri n ordine cresctoare ntr-un timp O(n)? Explicai cum sau de ce nu.

13.1-3 Dai un algoritm nerecursiv care efectueaz o traversare n inordine a unui arbore.
(Indicaie: Exist o soluie simpl care folosete o stiv pe post de structur de date auxiliar
i o soluie mai complicat dar n acelai timp mai elegant care nu mai folosete stiva, ns
presupune c exist o operaie care realizeaz testul de egalitate a doi pointeri.)

13.1-4 Dai algoritmi recursivi care realizeaz traversarea n preordine i postordine a unui
arbore cu n noduri ntr-un timp (n).

13.1-5 Argumentai c, deoarece sortarea a n elemente, care folosete modelul comparaiei are
nevoie de un timp de (n lg n), n cazul cel mai defavorabil, orice algoritm pentru construirea
unui arbore binar de cutare care se bazeaz pe comparaii i care folosete la intrare o list
arbitrar avnd n elemente, necesit tot un timp de (n lg n) n cazul cel mai defavorabil.

13.2. Interogarea ntr-un arbore binar de cutare


Principala operaie efectuat pe un arbore binar de cutare este cutarea unei chei memorate
n acesta. n afar de operaia Caut, arborii binari de cutare permit i alte interogri precum
Minim, Maxim, Succesor i Predecesor. n aceast seciune vom examina aceste operaii i
vom arta c fiecare dintre ele se poate executa ntr-un timp O(h) pe un arbore binar de cutare
de nlime h.

Cutarea
Procedura urmtoare poate fi folosit la cutarea unui nod avnd cheia cunoscut, ntr-un
arbore binar de cutare. Fiind date un pointer x la rdcina arborelui i o valoare k a cheii,
Arbore-Caut returneaz un pointer la nodul avnd cheia k dac exist un asemenea nod n
arbore sau nil n caz contrar.
Arbore-Caut(x, k)
1: dac x = nil sau k = cheie[x] atunci
2: returneaz x
3: dac k < cheie[x] atunci
4: returneaz Arbore-Caut(stnga[x], k)
5: altfel
6: returneaz Arbore-Caut(dreapta[x], k)
13.2. Interogarea ntr-un arbore binar de cutare 211

Figura 13.2 Interogri ntr-un arbore binar de cutare. Pentru a cuta n arbore cheia 13, se parcurge,
ncepnd cu rdcina, drumul 15 6 7 13. Cheia minim din arbore este 2, care se determin
pornind de la rdcin i urmnd pointerii stnga. Cheia maxim din arbore este 20, determinat
ncepnd cu rdcina i urmnd pointerii dreapta. Succesorul nodului avnd cheia 15 este nodul avnd
cheia 17, deoarece aceast cheie este cheia minim din subarborele drept al nodului avnd cheia 15. Nodul
avnd cheia 13 nu are subarbore drept, prin urmare succesorul su este cel mai de jos nod strmo al
su al crui fiu stng este de asemenea strmo pentru 13. n cazul nodului avnd cheia 13, succesorul
este nodul avnd cheia 15.

Procedura ncepe cutarea cu rdcina i traseaz un drum n jos n arbore, aa cum se


ilustreaz n figura 13.2. Pentru fiecare nod x ntlnit, se compar cheia k cu cheie[x]. Dac
cele dou chei sunt egale, cutarea s-a terminat. Dac k are o valoare mai mic dect cheie[x],
cutarea continu n subarborele stng al lui x, deoarece din proprietatea arborelui binar de
cutare rezult c k nu poate fi memorat n subarborele drept al lui x. Simetric, dac k este
mai mare dect cheie[x], cutarea continu n subarborele drept al lui x. Nodurile traversate n
timpul aplicrii recursive a acestei proceduri formeaz un drum n jos, pornind de la rdcin,
deci timpul de execuie al procedurii Arbore-Caut este O(h), unde h este nlimea arborelui.
Aceeai procedur se poate scrie iterativ, prin derularea recursivitii ntr-un ciclu ct
timp. Versiunea iterativ este mai eficient pe majoritatea calculatoarelor.
Arbore-Caut-Iterativ(x, k)
1: ct timp x 6= nil i k 6= cheie[x] execut
2: dac k < cheie[x] atunci
3: x stnga [x]
4: altfel
5: x dreapta[x]
6: returneaz x

Minimul i maximul
Determinarea elementului avnd cheia minim dintr-un arbore binar de cutare se realizeaz
ntotdeauna urmnd pointerii fiu stnga ncepnd cu rdcina i terminnd cnd se ntlnete
nil, aa cum se ilustreaz n figura 13.2. Procedura urmtoare ntoarce un pointer la elementul
minim din subarborele a crui rdcin este nodul x.
212 Capitolul 13 Arbori binari de cutare

Arbore-Minim(x)
1: ct timp stnga[x] 6= nil execut
2: x stnga[x]
3: returneaz x

Proprietatea arborelui binar de cutare garanteaz corectitudinea algoritmului Arbore-


Minim. Dac un nod x nu are subarbore stng, atunci din faptul c fiecare cheie din subarborele
su drept este cel puin la fel de mare ca i cheie[x] rezult c cheia minim a subarborelui
avnd rdcina x este chiar cheie[x]. Dac nodul x are un subarbore stng, atunci deoarece orice
cheie din subarborele su drept este mai mare sau egal cu cheie[x] i orice cheie din subarborele
su stng este mai mic sau egal cu cheie[x], rezult c cheia minim din subarborele avnd
rdcina x este cheia minim a subarborelui avnd rdcina stnga[x].
Pseudocodul pentru procedura Arbore-Maxim este simetric.
Arbore-Maxim(x)
1: ct timp dreapta[x] 6= nil execut
2: x dreapta[x]
3: returneaz x

Deoarece ambele proceduri traseaz drumuri n jos n arbore, ele se execut ntr-un timp
O(h), unde h este nlimea arborelui n care se face cutarea.

Succesorul i predecesorul unui nod


Cunoscnd un nod dintr-un arbore binar de cutare, este important cteodat s putem
determina succesorul su n ordinea de sortare determinat de traversarea n inordine a arborelui.
Dac toate cheile sunt distincte, succesorul unui nod x este nodul avnd cea mai mic cheie mai
mare dect cheie[x]. Structura de arbore binar de cutare permite determinarea succesorului
unui nod chiar i fr compararea cheilor. Procedura urmtoare returneaz succesorul unui nod
x dintr-un arbore binar de cutare, dac succesorul exist, sau nil, dac x are cea mai mare
cheie din arbore.
Arbore-Succesor(x)
1: dac dreapta[x] 6= nil atunci
2: returneaz Arbore-Minim(dreapta[x])
3: y p[x]
4: ct timp y 6= nil i x = dreapta[y] execut
5: xy
6: y p[y]
7: returneaz y

Codul procedurii Arbore-Succesor trateaz dou alternative. Dac subarborele drept al


nodului x nu este vid, atunci succesorul lui x este chiar cel mai din stnga nod din acest subar-
bore drept, care este determinat n linia 2 prin apelul Arbore-Minim(dreapta[x]). De exemplu,
succesorul nodului cu cheia 15 din figura 13.2 este nodul cu cheia 17.
n cellalt caz, cnd subarborele drept al nodului x este vid i x are un succesor y, atunci
y este cel mai de jos strmo al lui x al crui fiu din stnga este de asemenea strmo al lui x.
13.2. Interogarea ntr-un arbore binar de cutare 213

n figura 13.2, succesorul nodului cu cheia 13 este nodul cu cheia 15. Pentru a-l determina pe
y, se traverseaz arborele de la x n sus pn cnd se ntlnete un nod care este fiul stng al
printelui su; acest lucru se realizeaz n liniile 37 ale codului procedurii Arbore-Succesor.
n cazul unui arbore de nlime h, timpul de execuie al procedurii Arbore-Succesor
este O(h) deoarece n ambele situaii se urmeaz fie un drum n josul arborelui, fie unul n susul
arborelui. Procedura Arbore-Predecesor, care este similar, se execut tot ntr-un timp O(h).
Rezultatele obinute pn acum se pot rezuma n teorema urmtoare.
Teorema 13.1 Pe un arbore binar de cutare de nlime h, operaiile pe mulimi dinamice
Caut, Minim, Maxim, Succesor i Predecesor se pot executa ntr-un timp O(h).

Exerciii
13.2-1 Presupunem c avem memorate ntr-un arbore binar de cutare numere cuprinse ntre 1
i 1000 i c dorim s cutm numrul 363. Care dintre urmtoarele iruri nu poate fi secvena
nodurilor examinate?
a. 2, 252, 401, 398, 330, 344, 397, 363.
b. 924, 220, 911, 244, 898, 258, 362, 363.
c. 925, 202, 911, 240, 912, 245, 363.
d. 2, 399, 387, 219, 266, 382, 381, 278, 363.
e. 935, 278, 347, 621, 299, 392, 358, 363.
13.2-2 Profesorul Bunyan crede c a descoperit o proprietate remarcabil a arborilor binari
de cutare. S presupunem c determinarea cheii k ntr-un astfel de arbore se termin ntr-o
frunz. mprind cheile din nodurile arborelui n trei mulimi A, B i C construite astfel: A
conine cheile nodurilor de la stnga drumului de cutare, B cheile de pe drumul de cutare,
iar C cheile de la dreapta drumului de cutare, profesorul Bunyan afirm c oricare trei chei
a A, b B i c C trebuie s ndeplineasc condiia a b c. Dai un contraexemplu ct
mai mic, care s infirme proprietatea descoperit de profesor.
13.2-3 Folosii proprietatea arborelui binar de cutare pentru a demonstra riguros corectitudi-
nea codului pentru procedura Arbore-Succesor.
13.2-4 Traversarea n inordine pentru un arbore binar de cutare avnd n noduri se poate
implementa prin gsirea elementului minim din arbore cu procedura Arbore-Minim i apoi
apelnd de n 1 ori procedura Arbore-Succesor. Demonstrai c acest algoritm se execut
ntr-un timp de (n).
13.2-5 Demonstrai c, ntr-un arbore binar de cutare de nlime h, prin k apeluri succesive
ale procedurii Arbore-Succesor, se consum un timp O(k + h), indiferent care este nodul de
pornire.
13.2-6 Fie T un arbore binar de cutare avnd toate cheile distincte, x un nod frunz i y
printele su. Artai c cheie[y] este fie cea mai mic cheie din T care este mai mare dect
cheie[x] fie cea mai mare cheie din T care este mai mic dect cheie[x].
214 Capitolul 13 Arbori binari de cutare

13.3. Inserarea i tergerea


Operaiile de inserare i tergere provoac modificarea mulimii dinamice reprezentat de
arborele binar de cutare. Structura de date trebuie modificat n sensul c ea trebuie pe de o
parte s reflecte inserarea sau tergerea, iar pe de alt parte s conserve proprietatea arborelui
binar de cutare. Aa cum vom vedea n cele ce urmeaz, modificarea unui arbore pentru a insera
un element nou, este relativ simpl (direct), pe cnd gestiunea tergerii unui element este mai
complicat.

Inserarea
Vom folosi procedura Arbore-Insereaz pentru a insera o nou valoare v ntr-un arbore
binar de cutare T . Procedurii i se transmite un nod z pentru care cheie[z] = v, stnga[z] = nil
i dreapta[z] = nil. Ea va modifica arborele T i unele dintre cmpurile lui z astfel nct z va fi
inserat pe poziia corespunztoare n arbore.

Arbore-Insereaz(T, z)
1: y nil
2: x rdcin[T ]
3: ct timp x 6= nil execut
4: yx
5: dac cheie[z] < cheie[x] atunci
6: x stnga[x]
7: altfel
8: x dreapta[x]
9: p[z] y
10: dac y = nil atunci
11: rdcin[T ] z
12: altfel dac cheie[z] < cheie[y] atunci
13: stnga[y] z
14: altfel
15: dreapta[y] z

Figura 13.3 ilustreaz modul de lucru al procedurii Arbore-Insereaz. Ca i Arbore-


Caut i Arbore-Caut-Iterativ, Arbore-Insereaz ncepe cu rdcina arborelui i
traseaz un drum n jos. Pointerul x va referi nodul din drum, iar pointerul y va referi printele
lui x. Dup iniializare, ciclul ct timp din liniile 38 asigur deplasarea acestor pointeri n josul
arborelui, selectarea alternativei la stnga sau la dreapta realizndu-se n funcie de rezultatul
comparrii cheilor cheie[z] i cheie[x], pn cnd x este setat pe nil. Acest nil ocup poziia n
care trebuie s fie plasat elementul z. Liniile 915 realizeaz setarea pointerilor pentru a realiza
efectiv inserarea lui z.
Ca i celelalte operaii primitive pe arborii de cutare, procedura Arbore-Insereaz se
execut ntr-un timp O(h) pe un arbore de nlime h.
13.3. Inserarea i tergerea 215

Figura 13.3 Inserarea unui element avnd cheia 13 ntr-un arbore binar de cutare. Nodurile haurate
deschis indic drumul n jos, de la rdcin la poziia n care se insereaz elementul. Linia ntrerupt
semnific legtura adugat la arbore pentru a insera elementul.

tergerea
Procedura pentru tergerea unui nod dat z dintr-un arbore binar de cutare primete ca
argument un pointer la z. Procedura ia n considerare toate cele trei situaii ilustrate n figura
13.4. Dac z nu are fii, se va modifica printele su p[z] pentru a-i nlocui fiul z cu nil. Dac
nodul are un singur fiu, z va fi eliminat din arbore prin inserarea unei legturi de la printele
lui z la fiul lui z. n sfrit, dac nodul are doi fii, se va elimina din arbore succesorul y al lui z,
care nu are fiu stng (vezi exerciiul 13.3-4) i apoi se vor nlocui cheia i datele adiionale ale
lui z cu cheia i datele adiionale ale lui y.
Pseudocodul procedurii Arbore-terge organizeaz puin diferit aceste trei situaii.

Arbore-terge(T, z)
1: dac stnga[z] = nil sau dreapta[z] = nil atunci
2: yz
3: altfel
4: y Arbore-Succesor(z)
5: dac stnga[y] 6= nil atunci
6: x stnga[y]
7: altfel
8: x dreapta[y]
9: dac x 6= nil atunci
10: p[x] p[y]
11: dac p[y] = nil atunci
12: rdcin[T ] x
13: altfel dac y =stnga[p[y]] atunci
14: stnga[p[y]] x
15: altfel
16: dreapta[p[y]] x
17: dac y 6= z atunci
18: cheie[z] cheie[y] se copiaz i datele adiionale ale lui y
19: returneaz y
216 Capitolul 13 Arbori binari de cutare

Figura 13.4 tergerea unui nod z dintr-un arbore binar de cutare. n fiecare situaie, nodul care se
terge este haurat mai deschis dect celelalte. (a) Dac z nu are fii, pur i simplu se terge. (b) Dac z
are un singur fiu, z se elimin din arbore. (c) Dac z are doi fii, se elimin succesorul y al su, care are
cel mult un fiu, i apoi se nlocuiete cheia i datele adiionale ale lui z cu cheia i datele adiionale ale
lui y.

n liniile 14, algoritmul determin nodul y care se va scoate din arbore. Nodul y este fie
chiar nodul de intrare z (dac z are cel mult un fiu) fie succesorul lui z (dac z are doi fii). Apoi,
n liniile 58, x se seteaz fie la fiul diferit de nil al lui y fie la nil dac y nu are fii. Nodul
y este eliminat din arbore n liniile 916 prin modificarea pointerilor din p[y] i x. Eliminarea
lui y este oarecum complicat de necesitatea unei gestionri adecvate a cazurilor extreme cnd
x = nil sau cnd y este rdcina arborelui. n sfrit, liniile 1718 se vor executa cnd a fost
eliminat succesorul y al lui z i ele realizeaz mutarea cheii i datelor adiionale ale lui y n z,
scriind peste vechiul coninut al cheii i al datelor adiionale. Nodul y este ntors ca rezultat de
13.4. Arbori binari de cutare construii aleator 217

ctre procedur n linia 19, pentru ca procedura apelant s poat s-l recicleze, punndu-l n
lista de noduri libere. Procedura se execut ntr-un timp O(h) pe un arbore de nlime h.
Pe scurt, am demonstrat urmtoarea teorem.

Teorema 13.2 Operaiile pe mulimi dinamice Insereaz i terge se pot executa ntr-un
timp O(h) pe un arbore de nlime h.

Exerciii
13.3-1 Dai o versiune recursiv a procedurii Arbore-Insereaz.

13.3-2 Presupunem c se construiete un arbore binar de cutare prin inserarea repetat a unor
valori distincte. Artai c numrul de noduri examinate la cutarea unei valori n arbore este cu
1 mai mare dect numrul de noduri examinate la prima inserare a respectivei valori n arbore.

13.3-3 Fiind dat o mulime de n numere, aceasta se poate sorta prin construirea unui arbore
binar de cutare (folosind repetat Arbore-Insereaz pentru inserarea numerelor unul cte
unul) urmat de tiprirea numerelor prin traversarea n inordine a arborelui. Care sunt timpii de
execuie corespunztori celui mai defavorabil caz, respectiv celui mai favorabil caz pentru acest
algoritm de sortare?

13.3-4 Artai c dac un nod dintr-un arbore binar de cutare are doi fii, atunci succesorul
su nu are fiu stng iar predecesorul su nu are fiu drept.

13.3-5 Fie o alt structur de date care conine un pointer la un nod y dintr-un arbore
binar de cutare. Ce probleme pot s apar dac predecesorul z al lui y este ters din arbore
cu procedura Arbore-terge? Cum s-ar putea rescrie aceast procedur pentru a elimina
dificultile aprute?

13.3-6 Operaia de tergere este comutativ (n sensul c dac se terge prima dat nodul x i
apoi nodul y se obine acelai rezultat ca i atunci cnd se terge prima dat nodul y i apoi
nodul x)? Demonstrai sau dai un contraexemplu.

13.3-7 Cnd nodul z din Arbore-terge are doi fii, se poate elimina din arbore predecesorul
su i nu succesorul. Unii au demonstrat c o strategie echitabil, care d aceeai prioritate
(atenie) predecesorului i succesorului produce performane empirice mai bune. Cum ar trebui
modificat algoritmul Arbore-terge pentru a implementa o astfel de strategie echitabil?

13.4. Arbori binari de cutare construii aleator


Am demonstrat c toate operaiile de baz pe un arbore binar de cutare se execut ntr-
un timp O(h), h fiind nlimea arborelui. nlimea unui arbore binar de cutare se schimb
continuu cnd se fac inserri i tergeri de noduri n/din arbore. Pentru a analiza comportamentul
arborilor binari de cutare, n practic, va trebui s facem anumite ipoteze statistice asupra
distribuiei cheilor i asupra irului de inserri i tergeri.
218 Capitolul 13 Arbori binari de cutare

Din pcate, se tie puin despre nlimea medie a unui arbore binar de cutare n cazul
cnd se folosesc att inserri ct i tergeri pentru a-l crea. Dac arborele ar fi creat numai prin
inserri, analiza ar fi mai simpl. Vom defini prin urmare noiunea de arbore binar de cutare
construit aleator cu n chei distincte, ca fiind acel arbore care se construiete prin inserarea
ntr-o ordine aleatoare a cheilor ntr-un arbore iniial vid, considernd c oricare dintre cele n!
permutri ale celor n chei este egal probabil. (Exerciiul 13.4-2 v va cere s artai c aceast
noiune este diferit de cea care presupune c orice arbore binar de cutare cu n chei are aceeai
probabilitate de apariie.) Scopul seciunii de fa este s demonstreze c nlimea medie a unui
arbore binar de cutare construit aleator avnd n chei este O(lg n).
Vom ncepe cu investigarea structurii arborilor binari de cutare care sunt construii folosind
numai operaii de inserare.

Lema 13.3 Notm cu T arborele care rezult prin inserarea a n chei distincte k1 , k2 , . . . , kn
(n ordine) ntr-un arbore binar de cutare iniial vid. Cheia ki este un strmo al cheii kj n T ,
pentru 1 i < j n, dac i numai dac:

ki = min{kl : 1 l i i kl > kj }

sau

ki = max{kl : 1 l i i kl < kj }.

Demonstraie. : Presupunem c ki este un strmo al lui kj . Notm cu Ti arborele care


rezult dup ce au fost inserate n ordine cheile k1 , k2 , . . . , ki . Drumul de la rdcin la nodul
ki n Ti este acelai cu drumul de la rdcin la nodul ki n T . De aici rezult c dac s-ar insera
n Ti nodul kj , acesta (kj ) ar deveni fie fiu stng, fie fiu drept al nodului ki . Prin urmare (vezi
exerciiul 13.2-6), ki este fie cea mai mic cheie dintre k1 , k2 , . . . , ki care este mai mare dect
kj , fie cea mai mare cheie dintre k1 , k2 , . . . , ki care este mai mic dect kj .
: Presupunem c ki este cea mai mic cheie dintre k1 , k2 , . . . , ki care este mai mare dect
kj . (Cazul cnd ki este cea mai mare cheie dintre k1 , k2 , . . . , ki care este mai mic dect kj se
trateaz simetric). Compararea cheii kj cu oricare dintre cheile de pe drumul de la rdcin la
ki n arborele T , produce aceleai rezultate ca i compararea cheii ki cu cheile respective. Prin
urmare, pentru inserarea lui kj se va parcurge drumul de la rdcin la ki , apoi kj se va insera
ca descendent al lui ki .
Urmtorul corolar al lemei 13.3 caracterizeaz precis adncimea unei chei n funcie de
permutarea de intrare.

Corolarul 13.4 Fie T arborele care rezult prin inserarea a n chei distincte k1 , k2 , . . . , kn (n
ordine) ntr-un arbore binar de cutare iniial vid. Pentru o cheie kj dat, unde 1 j n,
definim mulimile:

Gj = {ki : 1 i < j i kl > ki > kj pentru toi indicii l < i cu kl > kj }

Lj = {ki : 1 i < j i kl < ki < kj pentru toi indicii l < i cu kl < kj } .


13.4. Arbori binari de cutare construii aleator 219

Figura 13.5 Ilustrarea celor dou mulimi Gj i Lj care conin cheile de pe drumul de la rdcina
unui arbore binar de cutare la cheia kj = 17. (a) Nodurile care au cheile n Gj sunt haurate cu negru,
iar nodurile care au cheile n Lj sunt albe. Toate celelalte noduri sunt haurate cu gris. Drumul n jos
de la rdcin la nodul cu cheia kj este ngroat. Cheile care sunt la stnga liniei ngroate sunt mai
mici dect kj , iar cele de la dreapta acestei linii sunt mai mari dect kj . Arborele se construiete prin
inserarea cheilor n ordinea dat de prima list din (b). Mulimea G0j = {21, 25, 19, 29} conine acele
elemente care se insereaz nainte de 17 i sunt mai mari dect 17. Mulimea Gj = {21, 19} conine
acele elemente care modific minimul elementelor din G0j . Astfel, 21 este n Gj deoarece el este primul
element din mulime. Cheia 25 nu este n Gj deoarece este mai mare dect elementul minim curent,
adic 21. Cheia 19 este n Gj deoarece ea este mai mic dect minimul curent care este 21 i deci noul
minim curent va fi 19. Cheia 29 nu este n Gj deoarece este mai mare dect elementul minim curent,
adic 19. Structura mulimilor L0j i Lj este simetric.

Atunci cheile de pe drumul de la rdcin la kj sunt chiar cheile din Gj Lj iar adncimea
oricrei chei kj din T este
d(kj , T ) = |Gj | + |Lj |.

Figura 13.5 ilustreaz cele dou mulimi Gj i Lj . Gj conine toate cheile ki inserate nainte de
kj astfel nct ki este cea mai mic cheie din k1 , k2 , . . . , ki care este mai mare dect kj (structura
lui Lj este simetric). Pentru a nelege mai bine mulimea Gj , s ncercm s gsim o metod
de enumerare a elementelor sale. Dintre cheile k1 , k2 , . . . , kj1 vom considera n ordine numai
pe acelea care sunt mai mari dect kj . Aceste chei formeaz mulimea notat n figur cu G0j .
220 Capitolul 13 Arbori binari de cutare

Pe msur ce inserm cheile, vom reine, n timp real, minimul. Mulimea Gj va fi format din
acele chei care suprascriu minimul.
Pentru a facilita analiza, vom simplifica oarecum scenariul actual. S presupunem c,ntr-
o mulime dinamic, se insereaz pe rnd n numere distincte, cte unul o dat. Dac toate
permutrile numerelor respective sunt egal probabile, de cte ori se modific n medie minimul
mulimii numerelor deja inserate? Pentru a rspunde la aceast ntrebare, s presupunem c al
i-lea numr inserat este ki , pentru i = 1, 2, . . . , n. Probabilitatea ca ki s fie minimul primelor
i numere este 1/i, deoarece rangul (poziia) lui ki ntre primele i numere este egal probabil cu
oricare dintre cele i ranguri posibile. Prin urmare, numrul mediu de modificri ale minimului
mulimii este
n
X 1
= Hn ,
i=1
i

unde Hn = ln n + O(1) este al n-lea numr armonic (vezi relaia (3.5) i problema 6-2).
Prin urmare, ne ateptm ca numrul de modificri ale minimului s fie aproximativ egal cu
ln n, iar lema urmtoare arat c probabilitatea ca numrul s fie mult mai mare este foarte
mic.

Lema 13.5 Fie k1 , k2 , . . . , kn o permutare oarecare a unei mulimi de n numere distincte i fie
|S| variabila aleatoare care este cardinalul mulimii

S = {ki : 1 i n i kl > ki pentru orice l < i} . (13.1)

Atunci P r{|S| ( + 1)Hn } 1/n2 , unde Hn este al n-lea numr armonic, iar 4, 32 verific
ecuaia (ln 1) = 2.

Demonstraie. Putem considera c determinarea cardinalului mulimii S se face prin n ncercri


Bernoulli, avnd succes la a i-a ncercare dac ki este mai mic dect elementele k1 , k2 , . . . , ki1 .
Probabilitatea de a avea succes la a i-a ncercare este 1/i. ncercrile sunt independente deoarece
probabilitatea ca ki s fie minimul dintre elementele k1 , k2 , . . . , ki este independent de ordonarea
relativ a mulimii k1 , k2 , . . . , ki1 .
Putem folosi teorema 6.6 pentru a mrgini probabilitatea ca |S| ( + 1)Hn . Valoarea medie
pentru |S| este = Hn ln n. Deoarece > 1, din teorema 6.6 rezult
Hn
eHn
P r{|S| ( + 1)Hn } = P r{|S| Hn } = e(1ln )Hn
Hn
e(ln 1) ln n = n(ln 1) = 1/n2 ,

n care am folosit definiia lui .


Acum avem instrumente pentru a mrgini nlimea unui arbore binar de cutare construit
aleator.

Teorema 13.6 nlimea medie a unui arbore binar de cutare construit aleator cu n chei
distincte este O(lg n).
13.4. Arbori binari de cutare construii aleator 221

Demonstraie. Fie k1 , k2 , . . . , kn o permutare oarecare a celor n chei i fie T arborele binar de


cutare care rezult prin inserarea cheilor n ordinea specificat pornind de la un arbore iniial
vid. Vom discuta prima dat probabilitatea ca adncimea d(kj , T ) a unei chei date kj s fie
cel puin t, pentru o valoare t arbitrar. Conform caracterizrii adncimii d(kj , T ) din corolarul
13.4, dac adncimea lui kj este cel puin t, atunci cardinalul uneia dintre cele dou mulimi Gj
i Lj trebuie s fie cel puin t/2. Prin urmare,

P r{d(kj , T ) t} P r{|Gj | t/2} + P r{|Lj | t/2} . (13.2)

S examinm la nceput P r{|Gj | t/2}. Avem

P r{|Gj | t/2}
= P r{|{ki : 1 i < j i kl > ki > kj pentru orice l < i}| t/2}
P r{|{ki : i n i kl > ki pentru orice l < i}| t/2}
= P r{|S| t/2} ,

unde S este definit n relaia (13.1). n sprijinul acestei afirmaii, s observm c probabilitatea
nu va descrete dac vom extinde intervalul de variaie al lui i de la i < j la i n, deoarece prin
extindere se vor aduga elemente noi la mulime. Analog, probabilitatea nu va descrete dac se
renun la condiia ki > kj , deoarece prin aceasta se nlocuiete o permutare a (de regul) mai
puin de n elemente (i anume acele chei ki care sunt mai mari dect kj ) cu o alt permutare
oarecare de n elemente.
Folosind o argumentare similar, putem demonstra c

P r{|Lj | t/2} P r{|S| t/2} ,

i apoi, folosind inegalitatea (13.2) obinem:

P r{d(kj , T ) t} 2P r{|S| t/2} .

Dac alegem t = 2( + 1)Hn , unde Hn este al n-lea numr armonic iar 4.32 verific ecuaia
(ln 1) = 2, putem aplica lema 13.5 pentru a concluziona c

P r{d(kj , T ) 2( + 1)Hn } 2P r{|S| ( + 1)Hn } 2/n2 .

Deoarece discutm despre un arbore binar de cutare construit aleator i cu cel mult n noduri,
probabilitatea ca adncimea oricruia dintre noduri s fie cel puin 2( + 1)Hn este, folosind
inegalitatea lui Boole (6.22), de cel mult n(2/n2 ) = 2/n. Prin urmare, n cel puin 1 2/n din
cazuri, nlimea arborelui binar de cutare construit aleator este mai mic dect 2( + 1)Hn i
n cel mult 2/n din cazuri nlimea este cel mult n. n concluzie, nlimea medie este cel mult
(2( + 1)Hn )(1 2/n) + n(2/n) = O(lg n).

Exerciii
13.4-1 Descriei un arbore binar de cutare cu n noduri astfel ca adncimea medie a unui nod
n arbore s fie (lg n) iar nlimea arborelui s fie (lg n). Ct de mare poate fi nlimea unui
arbore binar de cutare avnd n noduri dac adncimea medie a unui nod este (lg n)?
222 Capitolul 13 Arbori binari de cutare

13.4-2 Artai c noiunea de arbore binar de cutare avnd n chei ales arbitrar (suntem n
situaia n care oricare arbore binar de cutare avnd n chei este egal probabil a fi ales), este
diferit de noiunea de arbore binar de cutare avnd n noduri construit aleator, dat n aceast
seciune. (Indicaie: Analizai toate posibilitile pentru n = 3.)

13.4-3 ? Fiind dat o constant r 1, determinai pe t astfel nct probabilitatea ca nlimea


arborelui binar de cutare construit aleator s fie cel puin tHn , s fie mai mic dect 1/nr .

13.4-4 ? Considerm algoritmul Quicksort-Aleator ce are ca date de intrare un ir de n


numere. Demonstrai c pentru orice constant k > 0 toate cele n! permutri, mai puin O(1/nk )
dintre ele, se execut ntr-un timp O(n lg n).

Probleme
13-1 Arbori binari de cutare cu chei egale
Cheile egale pun probleme implementrii arborilor binari de cutare.

a. Care este performana asimptotic a algoritmului Arbore-Insereaz cnd acesta se


folosete pentru a insera n elemente cu chei identice ntr-un arbore binar de cutare, iniial
vid?

Ne propunem s mbuntim algoritmul Arbore-Insereaz testnd nainte de linia 5 dac


cheie[z] = cheie[x] i nainte de linia 12 dac cheie[z] = cheie[y]. Dac are loc egalitatea,
se va implementa una dintre strategiile descrise n continuare. Gsii pentru fiecare strategie
performana asimptotic a inserrii de n elemente avnd chei identice ntr-un arbore binar de
cutare iniial vid (Strategiile sunt descrise pentru linia 5, n care se compar cheile lui z i x.
Pentru a obine strategiile pentru linia 12, nlocuii x cu y).

b. Se folosete un comutator boolean b[x] pentru nodul x, i se seteaz x la stnga[x] sau


dreapta[x] n funcie de valoarea lui b[x], care va lua alternativ valorile Fals respectiv
Adevrat la fiecare vizitare a nodului n Arbore-Insereaz.

c. Se memoreaz o list de noduri avnd cheile egale cu cheia din x i se insereaz z n acea
list.

d. Se atribuie aleator lui x fie stnga[x], fie dreapta[x]. (Stabilii performana n cazul cel mai
defavorabil i deducei intuitiv performana n cazul mediu).

13-2 Arbori cu rdcin


Fiind date dou iruri de caractere a = a0 a1 . . . ap i b = b0 b1 . . . bq , n care fiecare ai i fiecare bj
sunt caractere dintr-o mulime ordonat de caractere, spunem c irul de caractere a este mai
mic lexicografic dect irul de caractere b dac se verific una dintre condiiile urmtoare:

1. exist un ntreg j, 0 j min(p, q), astfel nct ai = bi pentru orice i = 0, 1, . . . j 1 i


aj < bj , sau

2. p < q i ai = bi pentru orice i = 0, 1, . . . p.


Probleme 223

Figura 13.6 Un arbore cu rdcin care memoreaz irurile de bii 1011, 10, 011, 100 i 0. Fiecare cheie
a unui nod se poate determina prin traversarea drumului de la rdcin la nodul respectiv. Prin urmare
nu este nevoie s memorm cheile n noduri; cheile sunt afiate numai n scop ilustrativ. Nodurile sunt
haurate cu negru dac cheile care le corespund nu sunt n arbore; astfel de noduri sunt prezente numai
pentru a stabili un drum spre alte noduri.

De exemplu, dac a i b sunt iruri de bii, atunci 10100 < 10110 pe baza regulii 1 (punnd
j = 3), iar 10100 < 101000 pe baza regulii 2. Aceast ordonare este similar celei folosite n
dicionarele limbii engleze (i nu numai).
Structura de date arbore cu rdcin ilustrat n figura 13.6 memoreaz irurile de bii
1011, 10, 011, 100 i 0. Dac dorim s cutm o cheie a = a0 a1 . . . ap i ne aflm ntr-un nod
de adncime i, vom merge la stnga dac ai = 0 i la dreapta dac ai = 1. Fie S o mulime de
iruri de caractere binare distincte care au suma lungimilor egal cu n. Artai cum se folosete
arborele ce rdcin pentru a sorta lexicografic S ntr-un timp (n). De exemplu, n figura 13.6
rezultatul sortrii va fi irul 0, 011, 10, 100, 1011.
13-3 Adncimea medie a unui nod ntr-un arbore binar de cutare construit aleator
n aceast problem vom demonstra c adncimea medie a unui nod ntr-un arbore binar de
cutare avnd n noduri construit aleator este O(lg n). Cu toate c acest rezultat este mai slab
dect cel dat n teorema 13.6, tehnica pe care o vom folosi relev o similaritate surprinztoare
ntre construirea unui arbore binar de cutare i execuia algoritmului Quicksort-Aleator din
seciunea 8.3. Ne reamintim din capitolul 5 c lungimea drumului interior P (T ) al unui arbore
binar T este suma adncimilor nodurilor x, notat cu d(x, T ) peste toate nodurile x din T .
a. Demonstrai c adncimea medie a unui nod n T este
1 X 1
d(x, T ) = P (T ).
n n
xT

Acum dorim s artm c valoarea medie pentru P (T ) este O(n lg n).


b. Notm cu TL i respectiv TR subarborele stng, respectiv subarborele drept al arborelui
T . Demonstrai c dac T are n noduri, atunci
P (T ) = P (TL ) + P (TR ) + n 1.
224 Capitolul 13 Arbori binari de cutare

c. Notm cu P (n) lungimea medie a drumului interior al unui arbore binar de cutare
construit aleator avnd n noduri. Artai c

n1
1X
P (n) = (P (i) + P (n i 1) + n 1) .
n i=0

d. Artai c P (n) se poate rescrie astfel:

n1
2X
P (n) = P (k) + (n).
n
k=1

e. Reamintindu-v analiza versiunii aleatoare a algoritmului Quicksort, demonstrai c


P (n) = O(n lg n) .

La fiecare apelare recursiv a algoritmului Quicksort, alegem aleator un element pivot pentru
a partiiona mulimea elementelor de sortat. Fiecare nod al unui arbore binar de cutare mparte
n dou mulimea de elemente care aparin subarborelui cu rdcina n respectivul nod.

f. Descriei o implementare a algoritmului Quicksort n care comparrile efectuate pentru a


sorta o mulime de elemente sunt exact aceleai care se folosesc pentru a insera elementele
ntr-un arbore binar de cutare. (Ordinea n care se fac comparrile poate s difere, ns
trebuie fcute exact aceleai comparri.)

13-4 Numrul de arbori binari distinci


Notm cu bn numrul de arbori binari distinci avnd n noduri. n aceast problem vei gsi o
formul pentru bn i o estimare asimptotic.

a. Artai c b0 = 1 i c, pentru n 1,

n1
X
bn = bk bn1k .
k=0

b. Fie B(x) funcia generatoare


X
B(x) = bn xn
n=0

(vezi problema 4-6 pentru definiia funciilor generatoare). Artai c B(x) = xB(x)2 + 1
i de aici c

1
B(x) = (1 1 4x).
2x
Note bibliografice 225

Dezvoltarea n serie Taylor a lui f (x) n vecintatea punctului x = a este dat de



X f (k) (a) k
f (x) = (x a) ,
k!
k=0

unde f (k) (x) este derivata de ordinul k a lui f n punctul x.


c. Artai c

1 2n
bn =
n+1 n

(al n-lea numr Catalan) folosind dezvoltarea n serie Taylor a expresiei 1 4x n
vecintatea lui x = 0. (Dac dorii, putei folosi generalizarea dezvoltrii binomiale (6.5)
pentru exponeni nentregi n n locul dezvoltrii
n serie Taylor, n care pentru orice numr
real n i orice ntreg k, coeficientul binomial nk va fi interpretat ca n(n1) . . . (nk+1)/k!
dac k 0 i 0 n caz contrar.)
d. Artai c

4n
bn = (1 + O(1/n)).
n3/2

Note bibliografice
Knuth [123] conine o discuie pertinent a arborilor binari de cutare simpli i de asemenea
a numeroase variante ale acestora. Se pare c arborii binari de cutare au fost descoperii inde-
pendent de mai muli cercettori la sfritul anilor 50.
14 Arbori rou-negru

Capitolul 13 a artat c un arbore binar de cutare de nlime h poate implementa oricare


dintre operaiile de baz pe mulimi dinamice precum Caut, Predecesor, Succesor,
Minim, Maxim, Insereaz i terge ntr-un timp O(h). Prin urmare, operaiile pe mulimi
sunt rapide dac nlimea arborelui de cutare este mic; dac ns arborele are nlimea mare,
performanele operaiilor s-ar putea s nu fie mai bune dect cele ale listelor nlnuite. Arborii
rou-negru sunt un caz particular de arbori de cutare care sunt echilibrai n ideea garantrii
unui timp O(lg n) pentru cazul cel mai defavorabil al execuiei operaiilor de baz pe mulimi
dinamice.

14.1. Proprietile arborilor rou-negru


Un arbore rou-negru este un arbore binar de cutare care are un bit suplimentar pentru
memorarea fiecrui nod: culoarea acestuia, care poate fi rou sau negru. Prin restrngerea
modului n care se coloreaz nodurile pe orice drum de la rdcin la o frunz, arborii rou-negru
garanteaz c nici un astfel de drum nu este mai lung dect dublul lungimii oricrui alt drum,
deci c arborele este aproximativ echilibrat.
Fiecare nod al arborelui conine astfel cmpurile culoare, cheie, stnga, dreapta i p. Dac fiul
sau printele unui nod nu exist, cmpul pointer corespunztor din nod are valoarea nil. Vom
considera c aceste valori nil sunt pointeri la noduri (frunze) externe arborelui binar de cutare
i c nodurile obinuite, care conin chei, sunt noduri interne ale arborelui.
Un arbore binar de cutare este arbore rou-negru dac el ndeplinete urmtoarele
proprieti rou-negru:

1. Fiecare nod este fie rou, fie negru.

2. Fiecare frunz (nil) este neagr.

3. Dac un nod este rou, atunci ambii fii ai si sunt negri.

4. Fiecare drum simplu de la un nod la un descendent care este frunz conine acelai numr
de noduri negre.

n figura 14.1 este prezentat un exemplu de arbore rou-negru.


Numrul de noduri negre pe orice drum de la un nod (fr a include n numrare i nodul)
n jos spre o frunz se va numi nlime neagr a nodului i se va nota cu bh(x). Noiunea de
nlime neagr este bine definit pe baza proprietii 4, conform creia toate drumurile de la nod
n jos au acelai numr de noduri negre. Vom defini nlimea neagr a unui arbore rou-negru
ca fiind nlimea neagr a rdcinii sale.
Lema urmtoare va arta de ce arborii rou-negru sunt arbori de cutare eficieni.

Lema 14.1 Un arbore rou-negru cu n noduri interne are nlimea mrginit superior de
2 lg(n + 1).
14.1. Proprietile arborilor rou-negru 227

Figura 14.1 Un arbore rou-negru n care nodurile negre sunt nnegrite, iar nodurile roii sunt gri.
Fiecare nod dintr-un asemenea arbore este fie rou fie negru, fiecare frunz (nil) este neagr, fiii unui
nod rou sunt ambii negri, iar oricare drum simplu de la un nod la un descendent frunz conine acelai
numr de noduri negre. Fiecare nod diferit de nil este marcat cu un numr ce reprezint nlimea
neagr a nodului; nodurile nil au nlimea neagr egal cu 0.

Demonstraie. Vom arta la nceput c subarborele care are ca rdcin un nod oarecare x
conine cel puin 2bh(x) 1 noduri interne. Aceast afirmaie va fi demonstrat prin inducie
dup nlimea nodului x. Dac nlimea lui x este 0, atunci x trebuie s fie frunz (nil), iar
subarborele cu rdcina x conine cel puin 2bh(x) 1 = 20 1 = 0 noduri interne. Pentru pasul de
inducie vom considera un nod x care are nlimea pozitiv i este nod intern cu doi fii. Fiecare fiu
are nlimea neagr egal fie cu bh(x), fie cu bh(x) 1, n funcie de culoarea sa (rou, respectiv
negru). Deoarece nlimea unui fiu al lui x este mai mic dect nlimea lui x, putem aplica
ipoteza induciei pentru a demonstra c fiecare fiu are cel puin 2bh(x)1 1 noduri interne. Prin
urmare, subarborele cu rdcina x conine cel puin (2bh(x)1 1)+(2bh(x)1 1)+1 = 2bh(x) 1
noduri interne, ceea ce demonstreaz afirmaia de mai sus.
Pentru a termina demonstraia lemei, notm cu h nlimea arborelui. Conform proprietii
3, cel puin jumtate dintre nodurile de pe orice drum simplu de la rdcin la o frunz, fr a
numra i rdcina, trebuie s fie colorate cu negru. Prin urmare, nlimea neagr a rdcinii
trebuie s fie cel puin h/2; de aici rezult
n 2h/2 1.
Mutnd pe 1 n membrul stng i logaritmnd ambii membri, obinem c lg(n + 1) h/2 sau
c h 2 lg(n + 1).
O consecin imediat a acestei leme este c operaiile pe mulimi dinamice Caut, Minim,
Maxim, Succesor i Predecesor se pot implementa pe arborii rou-negru ntr-un timp
O(lg n), deoarece pe un arbore binar de cutare de nlime h aceste operaii se pot executa
ntr-un timp O(h) (dup cum s-a artat n capitolul 13) i deoarece orice arbore rou-negru
cu n noduri este un arbore de cutare cu nlimea O(lg n). Cu toate c algoritmii Arbore-
Insereaz i Arbore-terge prezentai n capitolul 13 se execut ntr-un timp O(lg n) pe un
arbore rou-negru, ei nu sprijin direct operaiile Insereaz i terge pe mulimi dinamice,
deoarece ei nu garanteaz c arborele binar de cutare rezultat prin aplicarea lor va rmne
228 Capitolul 14 Arbori rou-negru

arbore rou-negru. n seciunile 14.3 i 14.4 vom vedea c i aceste dou operaii se pot executa
ntr-un timp O(lg n).

Exerciii
14.1-1 Trasai arborele binar de cutare complet de nlime 3 avnd cheile {1, 2, . . . , 15}.
Adugai frunze nil i colorai nodurile n trei moduri diferite astfel nct nlimile negre ale
arborilor rou-negru rezultai s fie 2, 3 i respectiv 4.

14.1-2 Presupunem c rdcina unui arbore rou-negru are culoarea rou. Dac i schimbm
culoarea n negru, noul arbore este tot rou-negru?

14.1-3 Artai c cel mai lung drum simplu de la un nod x, dintr-un arbore rou-negru, la o
frunz descendent are lungimea cel mult dublul lungimii celui mai scurt drum simplu de la nodul
x la o frunz descendent.

14.1-4 Care este cel mai mare numr posibil de noduri interne ntr-un arbore rou-negru cu
nlimea neagr k? Dar cel mai mic?

14.1-5 Descriei un arbore rou-negru avnd n chei care are cel mai mare raport posibil dintre
numrul de noduri interne roii i numrul de noduri interne negre. Care este acest raport? Care
arbore are cel mai mic raport, i care este acest raport?

14.2. Rotaii
Executnd pe arbori rou-negru avnd n chei operaiile defimite pe arbori de cutare
Arbore-Insereaz i Arbore-terge va consuma un timp de O(lg n). Deoarece ele modific
arborele, se poate ntmpla ca rezultatul efecturii lor s ncalce proprietile rou-negru
enumerate n seciunea 14.1. Pentru a reface aceste proprieti, att culorile unora dintre nodurile
arborelui ct i structura pointerilor trebuie modificate.
Structura pointerilor se modific prin rotaie, operaie local ntr-un arbore de cutare ce
conserv ordonarea cheilor n inordine. Figura 14.2 ilustreaz cele dou tipuri de rotaii: rotaii
la stnga i rotaii la dreapta. Cnd se efectueaz o rotaie la stnga pe un nod x, presupunem
c fiul drept al acestuia, y, este diferit de nil. Rotaia la stnga pivoteaz n jurul legturii de
la x la y. Ea transform pe y n rdcin a subarborelui, pe x n fiu stng al lui y i pe fiul stng
al lui y n fiu drept al lui x.
Pseudocodul pentru Rotete-Stnga presupune c dreapta[x] 6= nil.
Figura 14.3 ilustreaz modul de operare al algoritmului Rotete-Stnga. Codul pentru
Rotete-Dreapta este similar. Att Rotete-Stnga ct i Rotete-Dreapta se execut
n timp O(1). Prin rotaie se modific numai pointerii; toate celelalte cmpuri ale nodului rmn
aceleai.
14.2. Rotaii 229

Figura 14.2 Operaii de rotaie pe un arbore binar de cutare. Operaia Rotete-Dreapta(T, y)


transform configuraia de dou noduri din stnga n configuraia prezentat n dreapta prin modificarea
unui numr constant de pointeri. Configuraia din dreapta se poate transforma n configuraia din stnga
prin operaia invers Rotete-Stnga(T, x). Cele dou noduri pot s apar oriunde ntr-un arbore binar
de cutare. Literele , i reprezint subarbori arbitrari. Operaia de rotaie conserv ordonarea cheilor
n inordine: cheile din sunt naintea lui cheie[x], care este naintea cheilor din , care la rndul lor
sunt mai mici dect cheie[y] i care, n sfrit, este mai mic dect cheile din .

Rotete-Stnga(T, x)
1: y dreapta[x] Seteaz y.
2: dreapta[x] stnga[y] Transform subarborele stng al lui y n subarbore drept al lui x.
3: dac stnga[y] 6= nil atunci
4: p[stnga[y]] x
5: p[y] p[x] Leag printele lui x de y.
6: dac p[x] = nil atunci
7: rdcin[T ] y
8: altfel
9: dac x =stnga[p[x]] atunci
10: stnga[p[x]] y
11: altfel
12: dreapta[p[x]] y
13: stnga[y] x Pune pe x ca fiu stng al lui y.
14: p[x] y

Exerciii
14.2-1 Trasai arborele rou-negru care rezult dup apelul procedurii Arbore-Insereaz
aplicat arborelui din figura 14.1, pentru cheia 36. Dac nodul inserat este colorat cu rou, va fi
arborele rezultat un arbore rou-negru? Dar dac este colorat cu negru?
14.2-2 Scriei pseudocodul pentru Rotete-Dreapta.
14.2-3 Fie a, b i c noduri arbitrare n subarborii , i respectiv din arborele plasat n partea
stng a figurii 14.2. Cum se modific adncimile nodurilor a, b i c cnd se efectueaz o rotaie
la dreapta pe nodul y din figur?
14.2-4 Artai c orice arbore binar de cutare avnd n noduri poate fi transformat n orice alt
arbore binar de cutare avnd n noduri, folosind O(n) rotaii. (Indicaie: Artai mai nti c
sunt suficiente cel mult n 1 rotaii la dreapta pentru a transforma arborele ntr-un lan spre
dreapta).
230 Capitolul 14 Arbori rou-negru

Figura 14.3 Un exemplu care ilustreaz modul n care procedura Rotete-Stnga(T, x) modific un
arbore binar de cutare. Frunzele nil sunt omise. Traversarea n inordine aplicat arborelui de intrare
i arborelui modificat produc aceeai list de valori de chei.

14.3. Inserarea
Inserarea unui nod ntr-un arbore rou-negru avnd n noduri se poate realiza ntr-un timp
O(lg n). Vom utiliza la nceput procedura Arbore-Insereaz (seciunea 13.3) pentru a insera
un nod x n arborele T considernd c T este un arbore binar de cutare obinuit i apoi l vom
colora pe x cu rou. Pentru a garanta conservarea proprietilor rou-negru, vom reface arborele
rezultat prin recolorarea nodurilor i efectuarea de rotaii. Majoritatea codului algoritmului RN-
Insereaz gestioneaz diversele cazuri ce pot apare n timpul refacerii proprietilor rou-negru
pentru arborele rezultat n urma execuiei algoritmului Arbore-Insereaz.
Codul algoritmului RN-Insereaz este mai puin complicat dect arat i l vom examina n
trei pai majori. La nceput vom determina ce nclcri ale proprietilor rou-negru se introduc
n liniile 12 cnd se insereaz n arbore nodul x i apoi acesta se coloreaz cu rou. Pe urm
vom examina motivaia principal a ciclului ct timp din liniile 319. n sfrit, vom explora
fiecare dintre cele trei cazuri n care se subdivide corpul ciclului ct timp i vom vedea cum sunt
atinse dezideratele. Figura 14.4 ilustreaz modul de funcionare al algoritmului RN-Insereaz
pe un arbore rou-negru eantion.
Care dintre proprietile rou-negru se pot nclca dup execuia liniilor 12? n mod sigur
proprietatea 1 se conserv, la fel i proprietatea 2, deoarece noul nod rou inserat are fiii setai pe
nil. Proprietatea 4, care afirm c numrul de noduri colorate cu negru este acelai pe orice drum
ce pleac dintr-un nod dat spre frunze, se pstreaz de asemenea, deoarece nodul x nlocuiete un
nod nil (negru), iar nodul x este rou i cu fiii colorai cu negru. Prin urmare, singura proprietate
14.3. Inserarea 231

care ar putea fi distrus este proprietatea 3, care afirm c un nod colorat cu rou nu poate avea
un fiu colorat i el cu rou. Mai exact, proprietatea 3 este nclcat dac printele lui x este
colorat cu rou, deoarece x este el nsui colorat astfel n linia 2. Figura 14.4(a) ilustreaz acest
caz dup ce nodul x a fost inserat i colorat cu rou.
RN-Insereaz(T, x)
1: Arbore-Insereaz(T, x)
2: culoare[x] rou
3: ct timp x 6=rdcin[T ] i culoare[p[x]]=rou execut
4: dac p[x] =stnga[p[p[x]]] atunci
5: y dreapta[p[p[x]]]
6: dac culoare[y] = rou atunci
7: culoare[p[x]] negru Cazul 1
8: culoare[y] negru Cazul 1
9: culoare[p[p[x]]] rou Cazul 1
10: x p[p[x]] Cazul 1
11: altfel
12: dac x = dreapta[p[x]] atunci
13: x p[x] Cazul 2
14: Rotete-Stnga(T, x) Cazul 2
15: culoare[p[x]] negru Cazul 3
16: culoare[p[p[x]]] rou Cazul 3
17: Rotete-Dreapta(T, p[p[x]]) Cazul 3
18: altfel
19: (La fel ca n clauza atunci interschimbnd dreapta cu stnga)
20: culoare[rdcin[T ]] negru

Scopul principal al ciclului ct timp din liniile 319 este s mute n sus n arbore nodul care
ncalc proprietatea 3 i n acelai timp s pstreze ca invariant proprietatea 4. La nceputul
fiecrei iteraii a ciclului, x va referi un nod colorat cu rou i care are printele colorat cu rou -
singura nclcare a proprietilor rou-negru din arbore. Exist dou rezultate posibile ale fiecrei
iteraii din ciclu: ori pointerul x se mut n sus n arbore, ori se efectueaz anumite rotaii i
ciclul se ncheie.
Exist de fapt ase cazuri care trebuie considerate n ciclul ct timp, ns trei dintre ele
sunt simetrice celorlalte trei, n funcie de cum printele p[x] al lui x este fiul stng sau fiul
drept al bunicului p[p[x]] al lui x, lucru care se determin n linia 4. Pseudocodul conine numai
cazul n care p[x] este fiul stng al printelui su, p[p[x]]. S-a fcut o presupunere important,
c rdcina arborelui este colorat cu negru - o proprietate care se garanteaz n linia 20 ori de
cte ori algoritmul se termin - deci p[x] nu este rdcina arborelui i p[p[x]] exist.
Cazul 1 se deosebete de cazurile 2 i 3 prin culoarea fratelui printelui lui x (unchiul lui
x). Linia 5 face pe y s refere unchiul dreapta[p[p[x]]] al lui x i apoi se face un test n linia 6.
Dac y este colorat cu rou, se execut cazul 1. Altfel, se vor executa cazurile 2 sau 3. n toate
cele trei cazuri, bunicul p[p[x]] al lui x este negru, deoarece printele p[x] al lui x este rou iar
proprietatea 3 este nclcat numai ntre x i p[x].
Prelucrrile corespunztoare cazului 1 (liniile 710) sunt ilustrate n figura 14.5. Acest caz
se execut cnd att p[x] ct i x sunt colorai cu rou. Deoarece p[p[x]] este colorat cu negru,
232 Capitolul 14 Arbori rou-negru

Figura 14.4 Modul de operare al algoritmului RN-Insereaz. (a) Nodul x dup inserare. Deoarece x
i printele su p[x] sunt ambii colorai cu rou, proprietatea 3 nu este verificat. Deoarece unchiul y al
lui x este tot rou, se poate folosi cazul 1 din cod. Nodurile sunt recolorate i pointerul x este mutat n
sus n arbore, rezultnd arborele prezentat n (b). Din nou, x i printele su p[x] sunt ambii colorai
cu rou, ns unchiul y al lui x este de data aceasta colorat cu negru. Deoarece x este fiul drept al lui
p[x], se poate folosi cazul 2. Se efectueaz o rotaie la stnga i arborele care rezult este prezentat n
(c). Acum x este fiul stng al printelui su i se va folosi cazul 3. Se efectueaz o rotaie la dreapta
care va produce arborele din (d), care este un arbore rou-negru valid.
14.3. Inserarea 233

att p[x] ct i x se pot colora cu negru, rezolvnd prin urmare conflictul c p[x] i x sunt ambii
colorai cu rou, i apoi vom colora pe p[p[x]] cu rou, conservnd astfel proprietatea 4. Singura
problem care poate s apar este ca p[p[x]] s aib la rndul su un printe colorat cu rou;
prin urmare trebuie s repetm ciclul ct timp cu p[p[x]] pe postul noului nod x.
n cazurile 2 i 3, culoarea unchiului y al lui x este neagr. Cele dou cazuri se deosebesc prin
aceea c x este fiul drept, respectiv fiul stng al lui p[x]. Liniile 1314 corespund cazului 2, care
este ilustrat mpreun cu cazul 3 n figura 14.6. n cazul 2, nodul x este fiul drept al printelui
su. Prin folosirea unei rotaii la stnga, acest caz se transform n cazul 3 (liniile 1517), n care
nodul x este fiul stng al printelui su. Deoarece att x ct i p[x] sunt colorai cu rou, rotaia
nu afecteaz nici nlimea neagr a nodurilor, nici proprietatea 4. Indiferent dac ajungem la
cazul 3 direct sau prin cazul 2, acum unchiul y al lui x este colorat cu negru, deoarece altfel
am fi executat cazul 1. n cazul 3 se execut dou schimbri de culoare i o rotaie la dreapta,
care conserv proprietatea 4, i apoi, deoarece nu mai avem dou noduri consecutive colorate cu
rou, am terminat. Corpul ciclului ct timp nu se va mai executa nc o dat deoarece acum
p[x] este colorat cu negru.
Care este timpul de execuie al algoritmului RN-Insereaz? Deoarece nlimea unui arbore
rou-negru avnd n noduri este O(lg n), apelul lui Arbore-Insereaz va consuma un timp
O(lg n). Corpul ciclului ct timp se repet numai cnd se execut cazul 1, i n acest caz pointerul
x urc n arbore. Prin urmare corpul ciclului ct timp se poate repeta tot de O(lg n) ori. n
concluzie, algoritmul RN-Insereaz se execut ntr-un timp total de O(lg n). Este interesant de
tiut c el nu execut niciodat mai mult de dou rotaii, deoarece ciclul ct timp se termin
n oricare din cazurile 2 i 3.

Exerciii
14.3-1 n linia 2 a algoritmului RN-Insereaz se seteaz la rou culoarea noului nod inserat x.
S observm c dac s-ar seta la negru culoarea lui x, atunci proprietatea 3 a arborilor rou-negru
nu ar fi nclcat. De ce nu s-a setat la negru culoarea lui x?

14.3-2 n linia 20 a algoritmului RN-Insereaz se seteaz la negru culoarea rdcinii. Care


este avantajul acestei operaii?

14.3-3 Desenai arborii rou-negru care rezult dup inserarea succesiv a cheilor 41, 38, 31,
12, 19, 8 ntr-un arbore rou-negru iniial vid.

14.3-4 Presupunem c nlimea neagr a fiecruia dintre subarborii , , , i din figurile


14.5 i 14.6 este k. Etichetai fiecare nod din cele dou figuri cu nlimea neagr a sa pentru a
verifica respectarea proprietii 4 prin transformrile indicate.

14.3-5 Considerm un arbore rou-negru format prin inserarea a n noduri, folosind algoritmul
RN-Insereaz. Demonstrai c dac n > 1 atunci arborele are cel puin un nod colorat cu rou.

14.3-6 Sugerai o implementare eficient a algoritmului RN-Insereaz n cazul n care


reprezentarea arborilor rou-negru nu conine informaii despre pointerii printe.
234 Capitolul 14 Arbori rou-negru

Figura 14.5 Cazul 1 al procedurii RN-Insereaz. Proprietatea 3 este nclcat deoarece x i printele
su p[x] sunt ambii colorai cu rou. Aceeai aciune este efectuat indiferent dac (a) x este fiul drept
sau (b) x este fiul stng. Fiecare dintre subarborii , , , i au rdcina colorat cu negru i toi au
aceeai nlime neagr. Codul pentru cazul 1 schimb culorile unor noduri, conservnd proprietatea 4:
toate drumurile n jos de la un nod fixat la frunze au acelai numr de noduri colorate cu negru. Ciclul
ct timp continu cu bunicul p[p[x]] al lui x pe post de noul nod x inserat. Orice nclcare a proprietii
3 poate s apar acum numai ntre noul x, care este colorat cu rou, i printele su, dac i acesta este
colorat cu rou.

14.4. tergerea
La fel ca i celelalte operaii de baz pe un arbore rou-negru cu n noduri, tergerea unui
nod consum un timp O(lg n). tergerea unui nod dintr-un arbore rou-negru nu este cu mult
mai complicat dect inserarea unui nod ntr-un astfel de arbore.
Pentru a face mai simple condiiile la limit (extreme) din cod, vom folosi o santinel pentru a
reprezenta nil (vezi pagina 176. Pentru un arbore rou-negru T , santinela nil[T ] este un obiect cu
aceleai cmpuri ca i un nod obinuit din arbore. Cmpul culoare al su este negru iar celelalte
cmpuri p, stnga, dreapta i cheie se pot seta la valori arbitrare. n arborele rou-negru,
toi pointerii la nil vor fi nlocuii cu pointeri la santinela nil[T ].
Santinelele se folosesc pentru a trata unitar toate nodurile arborelui: un fiu nil al unui nod
x se va putea considera ca i nod obinuit al crui printe este x. Am putea aduga cte un
14.4. tergerea 235

Figura 14.6 Cazurile 2 i 3 ale procedurii RN-Insereaz. Ca i n cazul 1, proprietatea 3 este nclcat
n oricare dintre cazurile 2 i 3 deoarece x i printele su p[x] sunt ambii colorai cu rou. Fiecare dintre
subarborii , , i au rdcina colorat cu negru i toi au aceeai nlime neagr. Cazul 2 se
transform n cazul 3 printr-o rotaie la stnga, care conserv proprietatea 4: toate drumurile n jos de
la un nod fixat la frunze au acelai numr de noduri colorate cu negru. Cazul 3 schimb culorile unor
noduri i efectueaz o rotaie la dreapta, care i ea conserv proprietatea 4. Apoi execuia ciclului ct
timp se termin, deoarece proprietatea 3 este verificat: nu mai exist dou noduri consecutive colorate
cu rou.

nod santinel distinct pentru fiecare nod nil din arbore, astfel c printele fiecrui nod nil ar fi
bine definit, ns aceast strategie ar nsemna un consum suplimentar de spaiu. n consecin,
vom folosi o singur santinel nil[T ] pentru a reprezenta toate nodurile nil. Cnd vom dori s
manipulm un fiu al unui nod x, va trebui s nu uitm s setm n prealabil p[nil[T ]] la x.

RN-terge(T, z)
1: dac stnga[z] = nil[T ] sau dreapta[z] = nil[T ] atunci
2: yz
3: altfel
4: y Arbore-Succesor(z)
5: dac stnga[y] 6= nil[T ] atunci
6: x stnga[y]
7: altfel
8: x dreapta[y]
9: p[x] p[y]
10: dac p[y] = nil[T ] atunci
11: rdcin[T ] x
12: altfel dac y =stnga[p[y]] atunci
13: stnga[p[y]] x
14: altfel
15: dreapta[p[y]] x
16: dac y 6= z atunci
17: cheie[z] cheie[y]
18: copiaz i celelalte cmpuri ale lui y
19: dac culoare[y] = negru atunci
20: RN-terge-Repar(T, x)
21: returneaz y
236 Capitolul 14 Arbori rou-negru

Procedura RN-terge reprezint o modificare minor a procedurii Arbore-terge (seci-


unea 13.3). Dup eliminarea nodului din arbore, ea apeleaz o procedur ajuttoare RN-ter-
ge-Repar care schimb culorile i efectueaz rotaiile necesare conservrii proprietilor rou-
negru.
Exist trei deosebiri ntre procedurile Arbore-terge i RN-terge. n primul rnd, toate
referirile la nil din Arbore-terge au fost nlocuite n RN-terge prin referine la nil[T ].
n al doilea rnd, testul pentru x 6= nil din linia 9 a lui Arbore-terge a fost eliminat, iar
atribuirea p[x] p[y] se face necondiionat n linia 9 a algoritmului RN-terge. Astfel, dac
x este santinela nil[T ], pointerul su printe va referi printele nodului y eliminat din arbore.
Ultima deosebire const n apelul procedurii RN-terge-Repar care se execut n liniile 1920
cnd y este colorat cu negru. Dac y este colorat cu rou, proprietile rou-negru sunt conservate
chiar dac y este eliminat din arbore, deoarece n arbore nu s-au modificat nlimile negre i nu
exist noduri adiacente colorate cu rou. Nodul x transmis procedurii RN-terge-Repar este
nodul care a fost unicul fiu al lui y nainte ca y s fie eliminat, dac y a avut un fiu diferit de
nil, sau santinela nil[T ] n cazul cnd y nu a avut fii. n ultimul caz atribuirea necondiionat
din linia 9 garanteaz c printele lui x este acum nodul care a fost anterior printele lui y,
indiferent dac x este un nod intern care conine o cheie sau este santinela nil[T ].
Acum putem s examinm modul n care procedura RN-terge-Repar restabilete
proprietile rou-negru ale arborelui de cutare.
RN-terge-Repar(T, x)
1: ct timp x 6=rdcin[T ] i culoare[x] = negru execut
2: dac x =stnga[p[x]] atunci
3: w dreapta[p[x]]
4: dac culoare[w] = rou atunci
5: culoare[w] negru Cazul 1
6: culoare[p[x]] rou Cazul 1
7: Rotete-Stnga(T, p[x]) Cazul 1
8: w dreapta[p[x]] Cazul 1
9: dac culoare[stnga[w]] = negru i culoare[dreapta[w]] = negru atunci
10: culoare[w] rou Cazul 2
11: x p[x] Cazul 2
12: altfel
13: dac culoare[dreapta[w]] = negru atunci
14: culoare[stnga[w]] negru Cazul 3
15: culoare[w] rou Cazul 3
16: Rotete-Dreapta(T, w) Cazul 3
17: w dreapta[p[x]] Cazul 3
18: culoare[w] culoare[p[x]] Cazul 4
19: culoare[p[x]] negru Cazul 4
20: culoare[dreapta[w]] negru Cazul 4
21: Rotete-Stnga(T, p[x]) Cazul 4
22: x rdcin[T ] Cazul 4
23: altfel
24: (La fel ca n clauza atunci interschimbnd dreapta cu stnga)
25: culoare[x] negru
14.4. tergerea 237

Dac nodul y eliminat n RN-terge este negru, tergerea lui are ca efect micorarea cu
1 a numrului de noduri negre de pe fiecare drum care a coninut acest nod. Prin urmare,
proprietatea 4 nu este respectat pentru toi strmoii nodului y. Acest inconvenient se poate
corecta considernd c nodul x are un negru suplimentar sau este dublu colorat cu negru.
Cu alte cuvinte, dac adugm 1 la numrul de noduri colorate cu negru de pe orice drum
care l conine pe x, atunci, n interpretarea de mai sus, proprietatea 4 este verificat. Cnd
vom elimina nodul y colorat cu negru, vom mpinge culoarea sa neagr n fiul su. Singura
problem care apare acum este aceea c nodul x ar putea fi dublu colorat cu negru, ceea ce
ncalc proprietatea 1.
Procedura RN-terge-Repar ncearc s refac proprietatea 1. Scopul ciclului ct timp
din liniile 124 este de a muta n sus n arbore nodul dublu colorat cu negru pn cnd

1. x refer un nod colorat cu rou, caz n care se va colora x cu negru n linia 25

2. x refer rdcina, caz n care nodul dublu colorat cu negru este doar eliminat sau

3. se pot efectua rotaii i recolorri adecvate.

n corpul ciclului ct timp, x refer ntotdeauna un nod colorat cu negru, care nu este rdcin i
care este dublu colorat cu negru. Linia 2 determin dac x este fiul stng sau drept al printelui
su p[x]. (Codul este dat pentru situaia n care x este fiul stng al printelui su; cazul cnd
x este fiu drept plasat n linia 24 este simetric). Se folosete un pointer w la fratele lui x.
Deoarece nodul x este dublu colorat cu negru, nodul w nu poate fi nil[T ]; dac ar fi, numrul
de noduri colorate cu negru pe drumul de la p[x] la nil, ar fi mai mic dect numrul de noduri
colorate cu negru pe drumul de la p[x] la x.
Cele patru cazuri expuse n cod sunt ilustrate n figura 14.7. nainte de a examina detaliat
fiecare caz n parte, s aruncm o privire general asupra modului n care se verific respectarea
proprietii 4 pentru transformrile efectuate n toate aceste cazuri. Ideea de baz este aceea
c n fiecare caz numrul de noduri colorate cu negru de la rdcin (incluznd i rdcina) la
fiecare dintre subarborii , , . . . , este conservat prin transformarea efectuat. De exemplu, n
figura 14.7(a), care corespunde cazului 1, numrul de noduri colorate cu negru de la rdcin la
oricare dintre subarborii sau este 3, att nainte ct i dup transformare. (S ne reamintim
c pointerul x refer un nod dublu colorat cu negru). Similar, numrul de noduri negre de la
rdcin la oricare dintre subarborii , , sau este 2, att nainte, ct i dup transformare. n
figura 14.7(b) numrarea trebuie s ia n considerare i culoarea c, care poate fi rou sau negru.
Dac notm numr(rou) = 0 i numr(negru) = 1, atunci numrul de noduri negre de la
rdcin la este 2+numr(c), att nainte, ct i dup transformare. Celelalte cazuri se pot
verifica ntr-o manier similar (exerciiul 14.4-5).
Cazul 1 (liniile 58 din RN-terge-Repar i figura 14.7(a)) apare cnd nodul w, fratele
nodului x, este colorat cu rou. Deoarece w trebuie s aib fiii colorai cu negru, putem
interschimba culorile lui w i p[x] i apoi s efectum o rotaie la stnga n p[x] fr a nclca nici
una dintre proprietile rou-negru. Noul frate al lui x, unul dintre fiii lui w, este acum colorat
cu negru i prin urmare am transformat cazul 1 ntr-unul din cazurile 2, 3 sau 4.
Cazurile 2, 3 i 4 apar cnd nodul w este colorat cu negru; ele se deosebesc prin culorile fiilor
lui w. n cazul 2 (liniile 1011 din RN-terge-Repar i figura 14.7(b)), ambii fii ai lui w sunt
colorai cu negru. Deoarece i w este colorat cu negru, vom scoate afar un negru att de la x
ct i de la w, lsnd x numai cu un negru, punnd w pe rou i adugnd un negru suplimentar
238 Capitolul 14 Arbori rou-negru

la p[x], care va deveni dublu colorat cu negru prin eliminarea negrului suplimentar din fiul su.
Apoi corpul ciclului ct timp se poate repeta cu p[x] pe post de nod x. S observm c dac
se ajunge la cazul 2 din cazul 1, atunci culoarea c a noului nod x este rou, deoarece nodul p[x]
original a fost rou, i prin urmare, dup execuia cazului 2, ciclul se va termina cnd se testeaz
condiia de ciclare.
Cazul 3 (liniile 1417 din RN-terge-Repar i figura 14.7(c)) apare cnd w este colorat
cu negru, fiul su stng este colorat cu rou, iar fiul su drept este colorat cu negru. Putem
interschimba culorile lui w i ale fiului su stng stnga[w] i apoi s efectum o rotaie la
dreapta n w fr a nclca proprietile rou-negru. Noul frate w al lui x este acum un nod
colorat cu negru care are un fiu drept colorat cu rou i prin urmare am transformat cazul 3 n
cazul 4.
Cazul 4 (liniile 1822 din RN-terge-Repar i figura 14.7(d)) apare cnd fratele w al
nodului x este colorat cu negru, iar fiul drept al lui w este colorat cu rou. Efectund anumite
schimbri de culoare i apoi o rotaie la stnga n p[x], se poate elimina negrul suplimentar din
x fr a nclca proprietile rou-negru. Setarea lui x ca rdcin provoac terminarea ciclului
ct timp cnd se testeaz condiia de continuare a ciclrii.
Care este timpul de execuie al procedurii RN-terge? Deoarece nlimea unui arbore
rou-negru avnd n noduri este O(lg n), costul total al procedurii fr a include i apelul lui RN-
terge-Repar este O(lg n). n RN-terge-Repar, fiecare din cazurile 1, 3 i 4 se termin
dup efectuarea unui numr constant de modificri de culoare urmate de cel mult trei rotaii.
Singurul caz n care corpul ciclului ct timp se repet este cazul 2, i n acesta pointerul x
se mut n sus n arbore de cel mult O(lg n) ori, fr a se efectua rotaii. n consecin, RN-
terge-Repar consum un timp de O(lg n) i efectueaz cel mult trei rotaii, iar timpul total
de execuie pentru RN-terge este de O(lg n).

Exerciii
14.4-1 Artai c dac un arbore rou-negru are rdcina colorat cu negru nainte de apelul
procedurii RN-terge, atunci culoarea rdcinii rmne aceeai i dup apel.
14.4-2 n exerciiul 14.3-3 ai determinat arborele rou-negru care rezult prin inserarea
succesiv a cheilor 41, 38, 31, 12, 19, 8 ntr-un arbore iniial vid. Desenai arborii rou-negru
care rezult prin tergerea succesiv a cheilor n ordinea 8, 12, 19, 31, 38, 41.
14.4-3 n care linii de cod din procedura RN-terge-Repar se inspecteaz sau se modific
santinela nil[T ]?
14.4-4 Simplificai codul procedurii Rotete-Stnga prin folosirea unei santinele pentru nil
i a unei alte santinele pentru a memora pointerul la rdcin.
14.4-5 Calculai numrul de noduri negre de la rdcin la fiecare dintre subarborii , , . . . ,
pentru fiecare din cazurile ilustrate n figura 14.7 i verificai dac fiecare numr rmne acelai
dup transformare. Dac un nod are culoarea c sau c0 , folosii notaia numr(c) sau numr(c0 )
pentru a exprima respectivul numr.
14.4-6 Presupunem c se insereaz un nod x ntr-un arbore rou-negru folosind procedura RN-
Insereaz i apoi acesta este ters imediat cu procedura RN-terge. ntrebarea este: arborele
care rezult dup tergerea lui x este identic cu arborele de dinainte de inserarea lui x? Justificai
rspunsul.
14.4. tergerea 239

Figura 14.7 Cazurile coninute n corpul ciclului ct timp al procedurii RN-terge. Nodurile
nnegrite sunt colorate cu negru, cele haurate cu gri nchis sunt colorate cu rou, iar cele haurate
cu gri deschis, care pot s fie colorate fie cu rou, fie cu negru, sunt notate cu c i c0 . Literele , , . . . ,
reprezint subarbori arbitrari. n fiecare caz, configuraia din stnga se transform n configuraia din
dreapta prin schimbarea unor culori i/sau efectuarea unei rotaii. Nodul referit de x este dublu colorat
cu negru. Singurul caz care provoac repetarea ciclrii este cazul 2. (a) Cazul 1 se transform ntr-unul
din cazurile 2, 3 sau 4 prin interschimbarea culorilor nodurilor B i D i efectuarea unei rotaii la stnga.
(b) n cazul 2, negrul suplimentar reprezentat de pointerul x se mut n sus n arbore prin colorarea
nodului D cu rou i setarea lui x pentru a referi nodul B. Dac se ajunge la cazul 2 de la cazul 1,
ciclul ct timp se termin deoarece culoarea c este rou. (c) Cazul 3 se transform n cazul 4 prin
interschimbarea culorilor nodurilor C i D i efectuarea unei rotaii la dreapta. (d) n cazul 4, negrul
suplimentar reprezentat de x se poate elimina prin schimbarea unor culori i efectuarea unei rotaii la
stnga (fr a nclca proprietile rou-negru) i apoi ciclul se termin.
240 Capitolul 14 Arbori rou-negru

Probleme
14-1 Mulimi dinamice persistente
n timpul descrierii unui algoritm avem cteodat nevoie s pstrm versiunile anterioare ale
unei mulimi dinamice cnd aceasta se modific. O astfel de mulime se numete persistent.
O modalitate de implementare a unei mulimi persistente este copierea ntregii mulimi ori de
cte ori aceasta se modific, ns aceast abordare poate ncetini programul i n acelai timp
consum mult spaiu. n unele situaii putem s procedm mai eficient.
Fie o mulime persistent S cu operaiile Insereaz, terge i Caut, care este
implementat folosind arbori binari de cutare, dup cum se arat n figura 14.8(a). Pentru
fiecare versiune a mulimii se memoreaz o rdcin distinct. Pentru a insera cheia 5 n mulime,
se creeaz un nod nou avnd cheia 5. Acest nod devine fiul stng al unui nod nou cu cheia 7,
deoarece nu putem modifica nodul existent avnd cheia 7. Similar, noul nod avnd cheia 7 devine
fiul stng al unui nod nou cu cheia 8 al crui fiu din dreapta este un nod existent avnd cheia
10. Noul nod cu cheia 8 devine, la rndul su, fiul drept al unei rdcini noi r0 avnd cheia 4 al
crei fiu stng este nodul existent cu cheia 3. Prin urmare se va copia numai o parte din arborele
iniial, aa cum se ilustreaz n figura 14.8(b).
Presupunem c fiecare nod din arbore are cmpurile cheie, stnga i dreapta, ns nu are un
cmp printe. (Vezi i exerciiul 14.3-6).

a. Identificai nodurile care trebuie modificate la inserarea unei chei k i la tergerea unui nod
y ntr-un/dintr-un arbore binar de cutare general i persistent.

b. Scriei o procedur Persistent-Arbore-Insereaz care, pentru un arbore persistent T


i o cheie k de inserat, ntoarce un arbore persistent nou T 0 care este rezultatul inserrii
cheii k n T .

c. Dac nlimea unui arbore binar de cutare persistent T este h, care sunt cerinele de timp
i spaiu pentru implementarea pe care ai dat-o pentru Persistent-Arbore-Insereaz?
(Cerinele de spaiu sunt proporionale cu numrul de noduri noi alocate).

d. Presupunem acum c fiecare nod are i un cmp printe. n acest caz, Persistent-
Arbore-Insereaz are nevoie de copierea unor informaii suplimentare. Demonstrai c
Persistent-Arbore-Insereaz va avea nevoie de un timp i spaiu (n), unde n este
numrul de noduri din arbore.

e. Artai cum se pot folosi arborii rou-negru pentru a se garanta c cerinele de timp i
spaiu n cazul cel mai defavorabil sunt de O(lg n) pentru inserare sau tergere.

14-2 Operaii de uniune pe arbori rou-negru


Operaia de uniune are ca argumente dou mulimi dinamice S1 i S2 i un element x astfel nct
pentru orice x1 S1 i x2 S2 are loc relaia cheie[x1 ] cheie[x] cheie[x2 ]. Ea returneaz o
mulime S = S1 {x} S2 . n aceast problem investigm modul de implementare al operaiei
de uniune pe arbori rou-negru.
Note bibliografice 241

Figura 14.8 (a) Un arbore binar de cutare avnd cheile 2, 3, 4, 7, 8, 10. (b) Arborele binar de cutare
persistent care rezult prin inserarea cheii 5. Cea mai recent versiune a mulimii const din nodurile
ce se pot accesa din rdcina r0 , iar versiunea anterioar este format din nodurile ce se pot accesa din
rdcina r. Nodurile haurate cu gri nchis sunt cele adugate pentru inserarea cheii 5.

a. Fiind dat un arbore rou-negru T , vom memora nlimea neagr a sa n cmpul bh[T ].
Artai c acest cmp se poate ntreine prin algoritmii RN-Insereaz i RN-terge fr
a fi nevoie de spaiu suplimentar de memorie n arbore i fr a mri timpii de execuie
asimptotici. Artai c nlimea neagr a fiecrui nod se poate determina pe parcursul
coborrii n T ntr-un timp O(1) pentru fiecare nod vizitat.

Dorim s implementm operaia RN-Uniune(T1 , x, T2 ) care distruge T1 i T2 i ntoarce arborele


rou-negru T = T1 {x} T2 . Notm cu n numrul total de noduri din T1 i T2 .

b. Fr a restrnge generalitatea, presupunem c bh[T1 ] bh[T2 ]. Descriei un algoritm de


timp O(lg n) care determin nodul colorat cu negru din T1 cu cea mai mare cheie i care
are nlimea neagr egal cu bh[T2 ].
c. Notm cu Ty subarborele avnd rdcina y. Descriei cum se poate nlocui Ty cu Ty {x}T2
ntr-un timp O(1) i fr a distruge proprietatea arborelui binar de cutare.
d. Ce culoare trebuie atribuit lui x pentru a conserva proprietile rou-negru 1, 2 i 4?
Descriei cum se poate reface proprietatea 3 ntr-un timp O(lg n).
e. Artai c timpul de execuie al procedurii RN-Uniune este O(lg n).

Note bibliografice
Ideea echilibrrii arborelui de cutare se datoreaz lui Adelson-Velskii i Landis [2], care au
introdus o clas de arbori de cutare echilibrai numii arbori AVL. n arborii AVL, echilibrarea
este meninut prin rotaii, ns pentru a reface echilibrarea ar putea fi necesare (lg n) rotaii
dup tergerea unui nod dintr-un arbore avnd n noduri. O alt clas de arbori de cutare,
numii 2-3 arbori, a fost introdus de J. E. Hopcroft n 1970 (manuscris nepublicat). ntr-un
2-3 arbore echilibrarea se menine prin manipularea gradelor nodurilor din arbore. Capitolul 19
242 Capitolul 14 Arbori rou-negru

se ocup cu B-arborii, care sunt o generalizare a 2-3 arborilor i au fost introdui de Bayer i
McCreight [18].
Arborii rou-negru au fost inventai de Bayer [17] sub numele de B-arbori binari simetrici.
Proprietile lor au fost studiate n detaliu de Guibas i Sedgewick [93], care au introdus i
convenia de colorare rou/negru.
Dintre celelalte clase de arbori binari echilibrai, probabil cea mai interesant este cea a
arborilor splay, introdui de Sleator i Tarjan [177], care sunt auto-ajustabili. (O bun des-
criere a arborilor splay este dat de Tarjan [188]). Arborii splay ntrein echilibrarea fr nici o
condiie explicit de echilibrare, cum ar fi de exemplu culoarea. n locul unei astfel de condiii, se
execut operaii splay n arbore (care implic rotaii) ori de cte ori se face o accesare. Costul
amortizat (vezi capitolul 18) al fiecrei operaii pe un arbore cu n noduri este O(lg n).
15 mbogirea structurilor de date

n ingineria programrii apar uneori situaii care nu necesit dect o structur de date clasic,
exact ca n carte ca de exemplu lista dublu nlnuit, tabela de dispersie sau arborele binar
de cutare ns majoritatea problemelor care trebuie rezolvate impun o anumit doz de
creativitate. Totui, doar n puine cazuri este nevoie s se creeze un tip complet nou de structur
de date. Mult mai frecvent este situaia cnd este suficient adugarea de informaii (cmpuri)
suplimentare la o structur de date clasic pentru ca aceasta s se poat folosi n aplicaia
dorit. Desigur, mbogirea structurilor de date nu este ntotdeauna simpl, deoarece informaia
adugat trebuie s fie actualizat i ntreinut prin operaiile ordinare ale structurii de date
respective.
Acest capitol prezint dou structuri de date care se construiesc prin mbogirea arborilor
rou-negru. Seciunea 15.1 descrie o structur de date care posed operaiile generale de statistic
de ordine pe o mulime dinamic. Cu ajutorul acestora se poate determina rapid al i-lea cel mai
mic numr din mulime sau rangul unui element dat n ordonarea total a mulimii. Seciunea
15.2 abstractizeaz procesul de mbogire a unei structuri de date i d o teorem care poate
simplifica mbogirea arborilor rou-negru. Seciunea 15.3 folosete aceast teorem pentru a
uura proiectarea unei structuri de date pentru ntreinerea unei mulimi dinamice de intervale,
ca de exemplu intervalele de timp. Fiind dat un interval de interogare, se poate determina rapid
un interval din mulime care se suprapune cu intervalul dat.

15.1. Statistici dinamice de ordine


Capitolul 10 a introdus noiunea de statistic de ordine. Specific, a i-a statistic de ordine a
unei mulimi de n elemente, unde i {1, 2, . . . , n}, este elementul din mulime care are a i-a cea
mai mic cheie. Am artat c orice statistic de ordine se poate determina ntr-un timp O(n)
n cazul unei mulimi neordonate. n aceast seciune vom vedea cum se pot modifica arborii
rou-negru pentru ca orice statistic de ordine s se determine ntr-un timp O(lg n) i vom afla
cum se determin rangul unui element poziia acestuia n ordonarea liniar a mulimii tot
ntr-un timp O(lg n).
Figura 15.1 prezint o structur de date care posed operaii rapide de statistici de ordine. Un
arbore de statistic de ordine T este de fapt un arbore rou-negru care conine o informaie
suplimentar n fiecare nod. La cmpurile uzuale pentru un nod x dintr-un arbore rou-negru
cheie[x], culoare[x], p[x], stnga[x] i dreapta[x] se adaug un cmp nou, dimensiune[x]. Acest
cmp conine numrul de noduri (interne) din subarborele cu rdcina x (incluzndu-l i pe
x), adic dimensiunea subarborelui. Dac facem convenia dimensiune[nil] = 0, atunci are loc
identitatea:
dimensiune[x] = dimensiune[stnga[x]] + dimensiune[dreapta[x]] + 1
(Pentru a gestiona adecvat condiia extrem pentru nil, o implementare efectiv va face
explicit testul x 6=nil anterior accesrii cmpului dimensiune sau, mai simplu, ca n seciunea
14.4, va folosi o santinel nil[T ] pentru a-l reprezenta pe nil, cu dimensiune[nil[T ]] = 0.)
244 Capitolul 15 mbogirea structurilor de date

Figura 15.1 Un arbore de statistic de ordine care este de fapt un arbore rou-negru mbogit. Nodurile
haurate cu gri sunt roii, iar nodurile haurate cu negru sunt negre. Pe lng cmpurile uzuale, fiecare
nod x are un cmp dimensiune[x] care reprezint numrul de noduri din subarborele avnd rdcina x.

Regsirea unui element cu rangul cunoscut


nainte de a arta cum se ntreine informaia de dimensiune n timpul inserrii i tergerii,
s examinm implementarea a dou interogri de statistic de ordine care folosesc aceast
informaie suplimentar. ncepem cu o operaie care regsete un element cu rangul cunoscut.
Procedura SO-Selecteaz(x, i) returnraz un pointer la nodul care conine a i-a cea mai mic
cheie din subarborele avnd rdcina x. Pentru a determina a i-a cea mai mic cheie dintr-un
arbore de statistic de ordine T vom face apelul SO-Selecteaz(rdcin[T ], i).
SO-Selecteaz(x, i)
1: r dimensiune[stnga[x]] + 1
2: dac i = r atunci
3: returneaz x
4: altfel dac i < r atunci
5: returneaz SO-Selecteaz(stnga[x], i)
6: altfel
7: returneaz SO-Selecteaz(dreapta[x], i r)

Ideea pe care se bazeaz SO-Selecteaz este similar celei de la algoritmii de selecie


prezentai n capitolul 10. Valoarea lui dimensiune[stnga[x]] reprezint numrul de noduri care
sunt inspectate anterior lui x, la traversarea n inordine a subarborelui avnd rdcina x. Prin
urmare, dimensiune[stnga[x]] + 1 este rangul lui x n subarborele avnd rdcina x.
n linia 1 a algoritmului SO-Selecteaz se calculeaz r, rangul nodului x n subarborele
avnd rdcina x. Dac i = r, atunci nodul x este al i-lea cel mai mic element i x va fi returnat
n linia 3. Dac i < r, atunci al i-lea cel mai mic element se va gsi n subarborele stng al
lui x, prin urmare se va apela recursiv algoritmul pentru subarborele avnd rdcina stnga[x]
n linia 5. Dac i > r, atunci al i-lea cel mai mic element se va gsi n subarborele drept al
lui x. Deoarece n subarborele avnd rdcina x sunt r elemente care se inspecteaz naintea
15.1. Statistici dinamice de ordine 245

subarborelui drept al lui x la traversarea n inordine a arborelui, al i-lea cel mai mic element
din subarborele avnd rdcina x este al (i r)-lea cel mai mic element din subarborele avnd
rdcina dreapta[x]. Acest element se determin recursiv n linia 7.
Pentru a vedea cum funcioneaz SO-Selecteaz, s considerm cutarea pentru al 17-lea
cel mai mic element din arborele de statistic de ordine din figura 15.1. Se ncepe cu x egal cu
rdcina, a crei cheie este 26, i cu i = 17. Deoarece dimensiunea subarborelui stng al lui 26
este 12, rangul rdcinii 26 va fi 13. Prin urmare, tim deja c nodul cu rangul 17 este al 17 - 13
= 4-lea cel mai mic element din subarborele drept al lui 26. Dup apelul recursiv, x este nodul
avnd cheia 41, iar i = 4. Deoarece dimensiunea subarborelui stng al lui 41 este 5, rangul su n
subarborele n care acesta este rdcin, este 6. Prin urmare tim deja c nodul cu rangul 4 este
n al 4-lea cel mai mic element al subarborelui stng al lui 41. Dup apelul recursiv, x este nodul
avnd cheia 30, iar rangul su n subarborele pentru care este rdcin este 2. Prin urmare se
face un nou apel recursiv pentru a determina al 4 - 2 = 2-lea cel mai mic element din subarborele
avnd rdcina 38. La acest apel vom constata c subarborele stng are dimensiunea 1, ceea ce
nseamn c rdcina 38 este al 2-lea cel mai mic element. n consecin, acest ultim apel va
ntoarce un pointer la nodul avnd cheia 38 i execuia procedurii se termin.
Deoarece fiecare apel recursiv coboar un nivel n arborele de statistic de ordine, timpul
total pentru SO-Selecteaz este n cel mai defavorabil caz proporional cu nlimea arborelui.
Deoarece arborele este un arbore rou-negru, nlimea sa este O(lg n), unde n este numrul de
noduri. Prin urmare, timpul de execuie pentru SO-Selecteaz este O(lg n) pentru o mulime
dinamic avnd n elemente.

Determinarea rangului unui element


Fiind dat un pointer la un nod x dintr-un arbore de statistic de ordine T , procedura SO-
Rang returnneaz poziia lui x n ordinea liniar dat de traversarea n inordine a lui T .
SO-Rang(T, x)
1: r dimensiune[stnga[x]] + 1
2: y x
3: ct timp y 6=rdcin[T ] execut
4: dac y = dreapta[p[y]] atunci
5: r r + dimensiune[stnga[p[y]]] + 1
6: y p[y]
7: returneaz r

Procedura funcioneaz dup cum urmeaz. Rangul lui x poate fi considerat a fi numrul
de noduri inspectate naintea lui x la traversarea n inordine a arborelui plus 1. Se folosete
urmtorul invariant: la nceputul corpului ciclului ct timp din liniile 36, r este rangul lui
cheie[x] din subarborele avnd rdcina y. Acest invariant se calculeaz dup cum este descris
n continuare. n linia 1 se seteaz r la rangul lui cheie[x] din subarborele avnd rdcina x.
Datorit atribuirii y x din linia 2 invariantul este adevrat pentru prima execuie a testului
din linia 3. La fiecare iteraie a corpului ciclului ct timp, se lucreaz cu subarborele care are
rdcina p[y]. A fost contorizat deja numrul de noduri din subarborele avnd rdcina y care
precede pe x la traversarea n inordine, aa c va trebui s adunm la r numrul de noduri din
subarborele avnd rdcina fratele lui y care-l precede pe x la traversarea n inordine, plus 1,
pentru p[y] dac i p[y] l precede pe x. Dac y este un fiu stng, atunci att p[y], ct i toate
246 Capitolul 15 mbogirea structurilor de date

Figura 15.2 Actualizarea dimensiunii subarborilor n timpul rotaiilor. Cele dou cmpuri dimensiune
care trebuie actualizate sunt cele care sunt la capetele legturii n jurul creia se efectueaz rotaia.
Actualizrile sunt locale, necesitnd numai informaia dimensiune memorat n x, y i n rdcinile
subarborilor ilustrai prin triunghiuri.

nodurile din subarborele drept al lui p[y] sunt inspectate dup x la traversarea n inordine, deci
r nu se modific. Altfel, y este un fiu drept i toate nodurile din subarborele stng al lui p[y] sunt
inspectate naintea lui x, ca i p[y]. Prin urmare, n linia 5 se va aduna la valoarea curent a lui
r numrul dimensiune[stnga[p[y]]] + 1. Datorit atribuirii y p[y] invariantul este adevrat
pentru urmtoarea iteraie. Cnd y =rdcin[T ], procedura va returna valoarea lui r, care este
acum rangul lui cheie[x].
De exemplu, execuia algoritmului SO-Rang pe arborele de statistic de ordine din figura
15.1 pentru a determina rangul nodului avnd cheia 38 va produce urmtoarea secven de valori
pentru cheie[y] i r nregistrate la nceputul corpului ciclului ct timp:
iteraia cheie[y] r
1 38 2
2 30 4
3 41 4
4 26 17
Procedura va returna rangul 17.
Deoarece fiecare iteraie a ciclului ct timp consum un timp de O(1), iar y urc un nivel n
arbore la fiecare iteraie, timpul de execuie al algoritmului SO-Rang este, n cel mai defavorabil
caz, proporional cu nlimea arborelui: O(lg n) pentru un arbore de statistic de ordine avnd
n noduri.

ntreinerea dimensiunilor subarborilor


Fiind dat valoarea cmpului dimensiune din fiecare nod, procedurile SO-Selecteaz i
SO-Rang pot calcula rapid informaia de statistic de ordine. Dac ns aceste cmpuri nu se
pot ntreine eficient prin operaiile de baz ce modific arborii rou-negru, strdania noastr de
pn acum a fost n zadar. Vom arta acum c dimensiunile subarborilor se pot ntreine att
pentru inserare ct i pentru tergere, fr afectarea timpilor asimptotici de execuie ai acestor
operaii.
Am remarcat n seciunea 14.3 c operaia de inserare a unui nod ntr-un arbore rou-negru
const din dou faze. n prima faz se coboar n arbore ncepnd de la rdcin i se insereaz
nodul nou ca fiu al unui nod existent. A doua faz nseamn urcarea n arbore, modificnd
culorile i efectund la sfrit rotaii pentru a conserva proprietile rou-negru.
15.1. Statistici dinamice de ordine 247

Pentru a ntreine dimensiunile subarborilor n prima faz, se va incrementa cmpul


dimensiune[x] pentru fiecare nod x de pe drumul traversat de la rdcin n jos spre frunze. Noul
nod care se adaug va primi valoarea 1 pentru cmpul su dimensiune. Deoarece pe drumul
parcurs sunt O(lg n) noduri, costul suplimentar pentru ntreinerea cmpurilor dimensiune va
fi i el O(lg n).
n faza a doua, singurele modificri structurale ale arborelui rou-negru sunt produse de
rotaii, care sunt cel mult dou. Mai mult, rotaia este o operaie local: ea invalideaz
numai cmpurile dimensiune din nodurile incidente (de la capetele) legturii n jurul creia
se efectueaz rotaia. La codul procedurii Rotete-Stnga(T, x) dat n seciunea 14.2, vom
aduga urmtoarele dou linii:
1: dimensiune[y] dimensiune[x]
2: dimensiune[x] dimensiune[stnga[x]] + dimensiune[dreapta[x]] + 1
Figura 15.2 ilustreaz modul n care sunt actualizate cmpurile dimensiune. Pentru
procedura Rotete-Dreapta modificrile sunt simetrice.
Deoarece la inserarea unui nod ntr-un arbore rou-negru sunt necesare cel mult dou rotaii,
se consum suplimentar doar un timp O(1) pentru actualizarea cmpurilor dimensiune n faza
a doua a inserrii. n concluzie, timpul total necesar pentru inserarea unui nod ntr-un arbore
de statistic de ordine avnd n noduri este O(lg n) acelai din punct de vedere asimptotic cu
cel pentru arborii rou-negru obinuii.
tergerea unui nod dintr-un arbore rou-negru are de asemenea dou faze: prima opereaz
pe arborele binar de cutare, iar a doua necesit cel mult trei rotaii i n rest nu efectueaz
alte modificri structurale ale arborelui. (Vezi seciunea 14.4.) Prima faz elimin din arbore
un nod y. Pentru a actualiza dimensiunile subarborilor, vom traversa un drum n sus de la
nodul y la rdcin i vom decrementa cmpurile dimensiune ale nodurilor de pe acest drum.
Deoarece drumul are lungimea O(lg n) n cazul unui arbore rou-negru avnd n noduri, timpul
suplimentar consumat cu ntreinerea cmpurilor dimensiune n prima faz a tergerii unui nod
este O(lg n). Cele O(1) rotaii din faza a doua a tergerii sunt gestionate n aceeai manier ca
i n cazul inserrii. Prin urmare, att inserarea ct i tergerea, inclusiv ntreinerea cmpurilor
dimensiune, consum un timp O(lg n) pentru un arbore de statistic de ordine avnd n noduri.

Exerciii
15.1-1 Artai cum opereaz SO-Selecteaz(T, 10) pe arborele rou-negru T din figura 15.1.

15.1-2 Artai cum opereaz SO-Rang(T, x) pe arborele rou-negru T din figura 15.1 i nodul
x cu cheie[x] = 35.

15.1-3 Scriei o versiune nerecursiv a lui SO-Selecteaz.

15.1-4 Scriei o procedur recursiv SO-Rang-Cheie(T, k) care are ca date de intrare un arbore
de statistic de ordine T i o cheie k i ntoarce rangul cheii k n mulimea dinamic reprezentat
prin T . Presupunei c valorile cheilor din T sunt distincte.

15.1-5 Fiind dat un element x dintr-un arbore de statistic de ordine avnd n noduri i un
numr natural i, cum se poate determina ntr-un timp O(lg n) al i-lea succesor al lui x n
ordinea liniar a arborelui?
248 Capitolul 15 mbogirea structurilor de date

15.1-6 S observm c toate referirile la cmpul dimensiune din procedurile SO-Selecteaz


i SO-Rang au ca scop calcularea rangului lui x n subarborele avnd rdcina x. n consecin,
presupunem c memorm n fiecare nod rangul su n subarborele pentru care el este rdcin.
Artai cum se poate ntreine aceast informaie la inserare i tergere. (Reamintim c aceste
operaii au nevoie de rotaii.)

15.1-7 Artai cum se poate folosi un arbore de statistic de ordine pentru a numra inversiunile
(vezi problema 1-3) dintr-un tablou de dimensiune n ntr-un timp O(n lg n).

15.1-8 ? Considerm n coarde ntr-un cerc, fiecare definit de capetele sale. Descriei un
algoritm de timp O(n lg n) pentru determinarea numrului de perechi de coarde care se
intersecteaz n interiorul cercului. (De exemplu, dac cele n coarde sunttoate
diametre, acestea
se vor intersecta n centrul cercului i prin urmare rspunsul corect este n2 .) Presupunei c nu
exist dou coarde cu acelai capt.

15.2. Cum se mbogete o structur de date


La proiectarea algoritmilor apare frecvent problema mbogirii structurilor de date uzuale
pentru ca acestea s ofere funcionalitate suplimentar. Acest proces de mbogire va fi folosit
n seciunea urmtoare pentru a proiecta o structur de date care are operaii cu intervale. n
aceast seciune vom examina paii acestui proces de mbogire. De asemenea, vom demonstra
o teorem care ne va permite s mbogim mai simplu arborii rou-negru n multe situaii.
Procesul de mbogire a unei structuri de date se poate mpri n patru pai:

1. alegerea unei structuri de date suport,


2. determinarea informaiei suplimentare care trebuie inclus i ntreinut n structura de
date de baz,
3. verificarea posibilitii ntreinerii informaiei suplimentare n cazul operaiilor de baz care
modific structura suport, i
4. proiectarea noilor operaii.

Ca i n cazul altor metode de proiectare prezentate schematic, nu trebuie s respectm orbete


paii de mai sus n ordinea enumerat. Prin natura ei, munca de proiectare recurge frecvent la
ncercri i reveniri n caz de eec, iar realizarea activitilor prevzute n pai se face de regul n
paralel. Nu are nici un rost, de exemplu, s determinm informaia suplimentar i s proiectm
noile operaii (paii 2 i 4) dac nu vom putea ntreine eficient informaia suplimentar memorat
n structura de date. Totui, aceast metod n patru pai va asigura o abordare ordonat a
eforturilor de mbogire a unei structuri de date i o schem de organizare a documentaiei
referitoare la aceasta.
Paii de mai sus au fost exemplificai n seciunea 15.1 pentru proiectarea arborilor de
statistic de ordine. La pasul 1 am ales ca structur de date suport arborii rou-negru. O
indicaie asupra utilitii acestor arbori la obinerea statisticilor de ordine este dat de eficiena
operaiilor specifice mulimilor dinamice pe o ordine total, precum Minim, Maxim, Succesor
i Predecesor.
15.2. Cum se mbogete o structur de date 249

La pasul 2 am adugat cmpurile dimensiune, care conin, pentru fiecare nod x, dimensiunea
subarborelui avnd rdcina x. n general, informaia suplimentar are ca scop s fac operaiile
(proprii structurii mbogite) mai eficiente. De exemplu, am fi putut implementa operaiile SO-
Selecteaz i SO-Rang folosind numai cheile memorate n arbore, ns n acest caz timpul lor
de execuie nu ar fi fost O(lg n). Uneori aceast informaie suplimentar conine referine i nu
date, ca n exerciiul 15.2-1.
Pentru pasul 3, ne-am asigurat c operaiile de inserare i tergere pot ntreine cmpurile
dimensiune fr a-i altera eficiena asimptotic, ele executndu-se tot ntr-un timp O(lg n).
n cazul ideal, un numr mic de modificri ale structurii de date, trebuie s fie suficient pentru
a ntreine informaia suplimentar. De exemplu, dac am memora n fiecare nod rangul su
din arbore, atunci operaiile SO-Selecteaz i SO-Rang s-ar executa mai rapid, dar inserarea
unui nou element minim n arbore, ar provoca modificarea acestei informaii (rangul) n fiecare
dintre nodurile arborelui. n schimb, dac memorm dimensiunea subarborilor n locul rangului,
inserarea unui nou element va necesita modificarea informaiei suplimentare doar n O(lg n)
noduri.
La pasul 4, am proiectat operaiile SO-Selecteaz i SO-Rang. De fapt, mbogirea
structurii de date este impus tocmai de nevoia de a implementa operaii noi. Uneori, informaia
suplimentar se va putea folosi nu numai la proiectarea operaiilor noi, ci i la reproiectarea celor
proprii structurii de date suport, ca n exerciiul 15.2-1.

mbogirea arborilor rou-negru


n cazul n care o structur de date mbogit are la baz arbori rou-negru, putem s
demonstrm c anumite tipuri de informaii suplimentare se pot ntreine eficient prin inserare
i tergere, simplificndu-se astfel realizarea pasului 3. Demonstraia teoremei urmtoare este
similar argumentrii fcute n seciunea 15.1 referitoare la ntreinerea cmpului dimensiune
pentru arborii de statistic de ordine.

Teorema 15.1 (mbogirea unui arbore rou-negru)


Fie T un arbore rou-negru avnd n noduri i fie f un cmp suplimentar al acestuia. Dac
cmpul f din nodul x se poate calcula folosind numai informaia din nodurile x, stnga[x] i
dreapta[x], inclusiv f [stnga[x]] i f [dreapta[x]], atunci valorile cmpurilor f din toate nodurile
lui T se pot ntreine n timpul operaiilor de inserare i tergere fr a fi afectat performana
asimptotic de O(lg n) a acestor operaii.

Demonstraie. Ideea principal a demonstraiei se bazeaz pe faptul c modificarea cmpului


f dintr-un nod x se propag numai la strmoii lui x din arbore. Astfel, modificarea lui f [x]
s-ar putea s necesite actualizarea lui f [p[x]], i doar att; modificarea lui f [p[x]] s-ar putea
s necesite actualizarea lui f [p[p[x]]], i doar att; i tot aa urcm n arbore cte un nivel la
fiecare modificare. Acest proces se va termina cnd se actualizeaz f [rdcin[T ]], deoarece nu
mai exist alt nod care s depind de noua valoare. Deoarece nlimea unui arbore rou-negru
este O(lg n), modificarea unui cmp f dintr-un nod cere un timp de O(lg n) pentru actualizarea
nodurilor dependente de aceast modificare.
Inserarea unui nod x n T se desfoar n dou faze (vezi seciunea 14.3). Pe parcursul primei
faze x se insereaz ca fiu al unui nod existent p[x]. Valoarea lui f [x] se poate calcula ntr-un
timp de O(1) deoarece, prin ipotez, aceast valoare depinde numai de informaia existent n
250 Capitolul 15 mbogirea structurilor de date

celelalte cmpuri ale lui x i de informaia din fiii lui x; n acest caz, ambii fii ai lui x sunt nil.
O dat calculat valoarea f [x], modificarea ei se propag n sus n arbore. Prin urmare, timpul
total pentru prima faz a inserrii este O(lg n). n faza a doua singurele modificri structurale
ale arborelui provin din rotaii. Timpul total de actualizare al cmpurilor f este O(lg n) pentru
fiecare rotaie deoarece ntr-o rotaie se modific doar dou noduri. i deoarece la o inserare sunt
necesare cel mult dou rotaii, timpul total pentru inserare este tot O(lg n).
La fel ca inserarea, tergerea are tot dou faze (vezi seciunea 14.4). n prima faz se produc
modificri structurale n arbore n dou momente: cnd nodul care se terge este nlocuit cu
succesorul su i apoi cnd nodul care se terge sau succesorul su este eliminat din arbore.
Propagarea actualizrilor lui f provocate de aceste modificri necesit cel mult O(lg n) deoarece
modificrile sunt locale n arbore. Refacerea arborelui rou-negru din faza a doua a tergerii
necesit cel mult trei rotaii, iar fiecare rotaie necesit un timp cel mult egal cu O(lg n) pentru
a propaga actualizrile lui f . n consecin, timpul total consumat pentru tergere este acelai
cu cel consumat pentru inserare, adic O(lg n).
n multe situaii, cum ar fi ntreinerea cmpurilor dimensiune din arborii de statistic
de ordine, costul de actualizare dup o rotaie este O(1) i nu O(lg n), estimare folosit n
demonstraia teoremei 15.1. Exerciiul 15.2-4 conine un astfel de exemplu.

Exerciii
15.2-1 Artai cum se pot executa operaiile (interogrile) definite pe mulimi dinamice Minim,
Maxim, Succesor i Predecesor, ntr-un timp O(1), n cazul cel mai defavorabil, pe un arbore
mbogit de statistic de ordine. Performana asimptotic a celorlalte operaii pe arborii de
statistic de ordine trebuie s rmn aceeai.
15.2-2 Studiai dac nlimile negre ale nodurilor se pot considera cmpuri n nodurile unui
arbore, ntreinute corespunztor, fr ca performana asimptotic a oricreia dintre operaiile
arborilor rou-negru s fie afectat. Artai cum se poate realiza ntreinerea, dac rspunsul
este afirmativ sau justificai rspunsul negativ.
15.2-3 Studiai dac adncimile nodurilor dintr-un arbore rou-negru se pot considera cmpuri
ale nodurilor care se pot ntreine eficient. Artai cum se poate realiza ntreinerea dac
rspunsul este afirmativ sau justificai rspunsul negativ.
15.2-4 ? Fie un operator binar asociativ i fie a cmpul care trebuie ntreinut n fiecare
nod al unui arbore rou-negru. Presupunem c dorim s adugm fiecrui nod x din arbore
un cmp suplimentar f astfel nct f [x] = a[x1 ] a[x2 ] . . . a[xm ], unde x1 , x2 , . . . , xm este
lista n inordine a nodurilor din subarborele avnd rdcina x. Artai c aceste cmpuri f se
pot actualiza corespunztor ntr-un timp O(1) dup o rotaie. Modificnd puin argumentaia,
artai c i cmpurile dimensiune din arborii de statistic de ordine se pot ntreine ntr-un
timp O(1) pentru fiecare rotaie.
15.2-5 ? Dorim s mbogim arborii rou-negru cu o operaie numit RN-Enumer(x, a, b)
care afieaz toate cheile k din arborele rou-negru avnd rdcina x care verific relaia a
k b. Descriei modul n care se poate implementa RN-Enumer ntr-un timp (m + lg n),
unde m este numrul de chei care se afieaz, iar n este numrul de noduri interne din arbore.
(Indicaie: Nu este nevoie s se adauge cmpuri suplimentare la nodurile arborelui.)
15.3. Arbori de intervale 251

Figura 15.3 Trihotomia intervalelor, pentru dou intervale nchise i i i0 . (a) Cnd i i i0 se suprapun,
sunt patru situaii posibile; n fiecare dintre ele, jos[i] sus[i0 ] i jos[i0 ] sus[i]. (b) sus[i] < jos[i0 ].
(c) sus[i0 ] < jos[i].

15.3. Arbori de intervale


n aceast seciune vom mbogi arborii rou-negru pentru a realiza operaii pe mulimi
dinamice de intervale. Un interval nchis este o pereche ordonat de numere reale [t1 , t2 ] cu
t1 t2 . Intervalul [t1 , t2 ] reprezint mulimea {t R : t1 t t2 }. Intervalele deschise
sau semideschise nu conin nici una dintre marginile mulimii, respectiv nu conin una dintre
acestea. n aceast seciune vom presupune c intervalele cu care lucrm sunt nchise; extinderea
rezultatelor la intervale deschise sau semideschise este imediat.
Intervalele reprezint un instrument convenabil de reprezentare a evenimentelor care ocup
fiecare un interval continuu de timp. Am putea dori, de exemplu, s interogm o baz de date de
intervale de timp pentru a descoperi ce evenimente au aprut ntr-un anumit interval. Structura
de date prezentat n aceast seciune ofer un mijloc eficient de ntreinere a unei astfel de baze
de date de intervale.
Intervalul [t1 , t2 ] se poate reprezenta sub forma unui obiect i, care are cmpurile jos[i] = t1
(captul inferior ) i sus[i] = t2 (captul superior ). Spunem c intervalele i i i0 se suprapun
dac i i0 6= , adic dac jos[i] sus[i0 ] i jos[i0 ] sus[i]. Pentru orice dou intervale i i i0
are loc trihotomia intervalelor , adic ele verific doar una din urmtoarele trei proprieti:

a. i i i0 se suprapun,
b. sus[i] < jos[i0 ],
c. sus[i0 ] < jos[i].

n figura 15.3 sunt prezentate cele trei posibiliti.


Numim arbore de intervale un arbore rou-negru care ntreine o mulime dinamic de
elemente, n care fiecare element x conine un interval int[x]. Arborii de intervale au urmtoarele
operaii.
Interval-Insereaz(T, x) adaug la arborele de intervale T elementul x care are n
cmpul int un interval.
252 Capitolul 15 mbogirea structurilor de date

Figura 15.4 Un arbore de intervale. (a) O mulime de 10 intervale, sortate de jos n sus dup captul
din stnga (inferior). (b) Arborele de intervale care le reprezint. Traversarea n inordine a acestui arbore
va produce lista nodurilor sortat dup captul din stnga.

Interval-terge(T, x) terge elementul x din arborele de intervale T .


Interval-Caut(T, i) returneaz un pointer la un element x din arborele de intervale T
pentru care int[x] se suprapune cu intervalul i, sau nil dac n mulime nu exist un astfel
de element.
Figura 15.4 ilustreaz modul de reprezentare al unei mulimi de intervale cu ajutorul unui arbore
de intervale. Vom aplica metoda n patru pai descris n seciunea 15.2 pentru a proiecta arborele
de intervale i operaiile proprii acestuia.

Pasul 1: Structura de date suport


Am ales ca structur de date suport un arbore rou-negru n care fiecare nod x conine un
cmp interval int[x] i pentru care cheia nodului x este captul inferior, jos[int[x]], al intervalului.
Prin urmare, o traversare n inordine a structurii de date va produce o list a intervalelor,
ordonat dup captul inferior al acestora.

Pasul 2: Informaia suplimentar


Pe lng cmpul interval int[x], fiecare nod x va conine o valoare max[x] care reprezint
valoarea maxim a capetelor intervalelor memorate n subarborele avnd rdcina x. Deoarece
15.3. Arbori de intervale 253

captul superior al fiecrui interval este cel puin la fel de mare ca i captul inferior al acestuia,
max[x] va fi de fapt valoarea maxim a capetelor superioare ale intervalelor memorate n subar-
borele avnd rdcina x.

Pasul 3: ntreinerea informaiei suplimentare


Trebuie s verificm c inserarea i tergerea se pot executa ntr-un timp O(lg n) pe un ar-
bore de intervale avnd n noduri. Valoarea cmpului max[x] se poate determina dac se cunosc
intervalul int[x] i valorile max ale fiilor nodului x:
max[x] = max(sus[int[x]], max[stnga[x]], max[dreapta[x]]).
Folosind teorema 15.1, rezult c inserarea i tergerea se execut ntr-un timp O(lg n). De
fapt, actualizarea cmpurilor max dup o rotaie se poate realiza ntr-un timp O(1), aa cum se
arat n exerciiile 15.2-4 i 15.3-1.

Pasul 4: Proiectarea noilor operaii


Singura operaie care trebuie proiectat este Interval-Caut(T, i), care gsete un interval
din T suprapus pe intervalul i. Dac T nu conine nici un astfel de interval, se returneaz nil.
Interval-Caut(T, i)
1: x rdcin[T ]
2: ct timp x 6= nil i i nu se suprapune cu int[x] execut
3: dac stnga[x] 6= nil i max[stnga[x]] jos[i] atunci
4: x stnga[x]
5: altfel
6: x dreapta[x]
7: returneaz x

Cutarea intervalului care se suprapune cu i ncepe iniializnd x cu rdcina arborelui i


continu cobornd n arbore. Ea se termin fie cnd s-a gsit un interval care se suprapune cu
i, fie cnd x devine nil. Deoarece fiecare iteraie a ciclului necesit un timp O(1) i deoarece
nlimea unui arbore rou-negru avnd n noduri este O(lg n), procedura Interval-Caut va
consuma un timp O(lg n).
nainte de a studia dac algoritmul Interval-Caut este corect, s examinm cum funcio-
neaz el pe arborele de intervale din figura 15.4. Presupunem c dorim s determinm un interval
care se suprapune cu intervalul i = [22, 25]. Se ncepe iniializnd x cu rdcina arborelui, care
conine intervalul [16, 21] care nu se suprapune cu i. Deoarece max[stnga[x]] = 23 este mai
mare dect jos[i] = 22, ciclul continu cu x iniializat cu fiul stng al rdcinii noul nod x care
conine intervalul [8, 9] i care nici el nu se suprapune cu i. De data aceasta, max[stnga[x]] =
10 este mai mic dect jos[i] = 22, deci ciclul continu iniializnd x cu fiul su drept. Intervalul
[15, 23] memorat n acest nod se suprapune cu i, deci procedura va returna acest nod.
Pentru a da un exemplu de cutare fr succes, s determinm intervalul care se suprapune cu
intervalul i = [11, 14] n arborele de intervale din figura 15.4. ncepem iniializnd x cu rdcina
arborelui. Deoarece intervalul memorat n rdcin nu se suprapune cu i i max[stnga[x]] = 23
este mai mare dect jos[i] = 11, vom continua cu fiul stng al lui x, nodul care conine intervalul
[8, 9]. (S observm c n subarborele drept nu exist nici un interval care s se suprapun
254 Capitolul 15 mbogirea structurilor de date

cu i vom vedea mai trziu de ce.) Intervalul din x, [8, 9] nu se suprapune cu i, i deoarece
max[stnga[x]] = 10 este mai mic dect jos[i] = 11 vom continua iniializnd x cu fiul su drept.
(S observm acum c n subarborele stng nu exist nici un interval care s se suprapun cu i.)
Intervalul din nodul x curent, adic [15, 23] nu se suprapune cu i, fiul su stng este nil, aa c
vom continua cu fiul su drept, care este i el nil, deci ciclul se ncheie i procedura returneaz
nil.
Pentru a studia corectitudinea algoritmului Interval-Caut, trebuie s nelegem de ce este
suficient s se examineze nodurile de pe un singur drum care pornete de la rdcin. Ideea de
baz este aceea c pentru orice nod x, dac int[x] nu se suprapune cu i, atunci cutarea continu
ntr-o direcie sigur: intervalul care se suprapune cu i va fi gsit cu siguran dac n arbore
exist un asemenea interval. Teorema urmtoare exprim mai riguros aceast proprietate.

Teorema 15.2 Considerm execuia unei iteraii a ciclului ct timp din algoritmul Interval-
Caut(T, i).
1. Dac se execut linia 4 (deci cutarea continu la stnga), atunci fie c subarborele stng
al lui x conine intervalul care se suprapune cu i, fie c n subarborele drept nu exist nici
un interval care se suprapune cu i.
2. Dac se execut linia 6 (deci cutarea continu la dreapta), atunci n subarborele stng al
lui x nu exist nici un interval care se suprapune cu i.

Demonstraie. Ambele cazuri se demonstreaz folosind trihotomia intervalelor. Vom demonstra


la nceput cazul 2, acesta fiind mai simplu. S remarcm c dac se execut linia 6, atunci
datorit condiiei de ramificare din linia 3, avem fie stnga[x] = nil fie max[stnga[x]] < jos[i].
Dac stnga[x] = nil, atunci este evident c subarborele avnd rdcina stnga[x] nu conine
nici un interval care s se suprapun cu i deoarece el nu conine nici un nod, deci nici un
interval. Presupunem acum c stnga[x] 6= nil i c max[stnga[x]] < jos[i]. Fie i0 un interval
din subarborele stng al lui x (vezi figura 15.5(a)). Deoarece max[stnga[x]] este cel mai mare
capt de interval din subarborele stng al lui x, avem:
sus[i0 ] max[st
a nga[x]] < jos[i] ,
i din trihotomia intervalelor rezult c i i i0 nu se suprapun, deci am demonstrat cazul 2.
Pentru a demonstra cazul 1, putem presupune c n subarborele stng al lui x nu exist
intervale care s se suprapun cu i (dac ar exista astfel de intervale, am terminat demonstraia)
i atunci trebuie doar s demonstrm c nici n subarborele drept al lui x nu exist intervale
care s se suprapun cu i. S observm c dac se execut linia 4, atunci datorit condiiei
de ramificare din linia 3, avem max[stnga[x]] jos[i]. Mai mult, din definiia cmpului max
rezult c n subarborele stng al lui x trebuie s existe un interval i0 astfel nct:
sus[i0 ] = max[st
a nga[x]] jos[i].
(Figura 15.5(b) reflect aceast situaie). Deoarece i i i0 nu se suprapun i deoarece relaia
sus[i0 ] < jos[i] nu este adevrat, din trihotomia intervalelor rezult c sus[i] < jos[i0 ]. Deoarece
arborii de intervale au drept chei capetele din stnga ale intervalelor, din proprietatea arborelui
de cutare rezult c pentru orice interval i00 din subarborele stng al lui x are loc inegalitatea
sus[i] < jos[i0 ] jos[i00 ].
15.3. Arbori de intervale 255

Figura 15.5 Intervalele pentru demonstraia teoremei 15.2. Valoarea lui max[stnga[x]] este marcat
n fiecare caz cu o linie ntrerupt. (a) Cazul 2: cutarea continu la dreapta. Nu exist nici un interval
i0 care s se suprapun cu i. (b) Cazul 1: cutarea continu la stnga. Fie c subarborele stng al lui x
conine un interval care se suprapune cu i (aceast situaie nu este ilustrat n figur), fie c exist un
interval i0 n subarborele stng al lui x astfel ca sus[i0 ] = max[stnga[x]]. Deoarece i nu se suprapune cu
i0 , orice alt interval i00 din subarborele stng al lui x nu se va suprapune cu i deoarece jos[i0 ] jos[i00 ].

Conform trihotomiei intervalelor, rezult c i i i00 nu se suprapun.


Teorema 15.2 garanteaz c dac algoritmul Interval-Caut continu cu unul dintre fiii lui
x i nu se gsete nici un interval de suprapunere, atunci cutarea care ar continua cu cellalt
fiu al lui x ar fi de asemenea fr succes.

Exerciii
15.3-1 Scriei pseudocodul procedurii Rotete-Stnga care opereaz pe nodurile unui arbore
de intervale i care actualizeaz cmpurile max ntr-un timp O(1).

15.3-2 Rescriei codul pentru Interval-Caut astfel ca el s funcioneze adecvat n cazul cnd
toate intervalele sunt deschise.

15.3-3 Descriei un algoritm eficient care, fiind dat un interval i, returneaz fie un interval care
se suprapune cu i i care are captul din stnga minim, fie nil dac nu exist un asemenea
interval.

15.3-4 Fiind dai un arbore de intervale T i un interval i, descriei cum se poate determina
lista tuturor intervalelor din T care se suprapun cu i ntr-un timp O(min(n, k lg n)), unde k este
numrul de intervale din list. (Opional: Gsii o soluie care nu modific arborele.)

15.3-5 Sugerai modificri ale procedurilor pentru arborele de intervale pentru a putea
implementa operaia Interval-Caut-Exact(T, i), care returneaz fie un pointer la un nod
x din arborele de intervale pentru care jos[int[x]] = jos[i] i sus[int[x]] = sus[i], fie nil dac
T nu conine un astfel de nod. Toate operaiile, inclusiv Interval-Caut-Exact trebuie s se
execute ntr-un timp de O(lg n) pe un arbore avnd n noduri.

15.3-6 Artai cum se poate ntreine o mulime dinamic Q de numere, care pentru operaia
Min-Dif returneaz mrimea diferenei dintre cele mai apropiate dou numere din Q. De
exemplu, dac Q = {1, 5, 9, 15, 18, 22}, atunci Min-Dif(Q) va returna 18 - 15 = 3, deoarece 15
256 Capitolul 15 mbogirea structurilor de date

i 18 sunt cele mai apropiate numere din Q. Realizai operaiile Insereaz, terge, Caut i
Min-Dif ct mai eficient i analizai timpii lor de execuie.

15.3-7 ? Bazele de date de circuite VLSI reprezint un circuit integrat ca o list de drept-
unghiuri. Presupunem c fiecare dreptunghi este orientat rectiliniu (adic are laturile paralele
cu axele x i y ale sistemului de coordonate), deci reprezentarea unui dreptunghi const din
valorile minime i maxime ale coordonatelor sale x i y. Dai un algoritm ce consum un timp
de O(n lg n) pentru a decide dac o mulime de dreptunghiuri astfel reprezentate conine sau
nu dou dreptunghiuri care se suprapun. Algoritmul nu trebuie s determine toate perechile de
coordonate care se intersecteaz, ci doar s raporteze c exist suprapunere i n cazul cnd
un dreptunghi acoper n ntregime alt dreptunghi, chiar dac laturile lor nu se intersecteaz.
(Indicaie: Deplasai o linie de baleiaj peste mulimea de dreptunghiuri.)

Probleme
15-1 Punctul de suprapunere maxim
Presupunem c dorim s memorm punctul de suprapunere maxim asociat unei mulimi
de intervale punctul coninut n cele mai multe intervale din mulime. Artai cum se poate
ntreine eficient acest punct de suprapunere maxim cnd se insereaz sau se terg intervale
n/din mulime.

15-2 Permutarea Josephus


Permutarea Josephus se definete dup cum urmeaz. Presupunem c n persoane sunt
aranjate n cerc i c exist un ntreg pozitiv m n. ncepnd cu o persoan stabilit, se
parcurge cercul i fiecare a m-a persoan se scoate din configuraie. Dup ce persoana a fost
eliminat, numrarea continu cu configuraia rmas. Procesul de eliminare continu pn
cnd toate cele n persoane au fost scoase din configuraie. Ordinea n care se elimin persoanele
din configuraie va defini permutarea Josephus (n,m) a ntregilor 1, 2, . . . , n. De exemplu,
permutarea Josephus (7, 3) este h3, 6, 2, 7, 5, 1, 4i.
a. Presupunem c m este constant. Descriei un algoritm ce consum un timp O(n) care, fiind
dat un ntreg n, produce permutarea Josephus (n, m).
b. Presupunem c m nu este constant. Descriei un algoritm ce consum un timp O(n lg n)
care, fiind dai ntregii n i m, produce permutarea Josephus (n, m).

Note bibliografice
Preparata i Shamos [160] descriu cteva dintre tipurile de arbori de intervale care apar n
literatur. Dintre cei mai importani din punct de vedere teoretic amintim aici cei descoperii
independent de H. Edelsbrunner (1980) i E.M. McCreight (1981), care, ntr-o baz de date cu
n intervale, permit enumerarea tuturor celor k intervale care suprapun un interval de interogare
dat ntr-un timp O(k + lg n).
IV Tehnici avansate de proiectare i analiz
Introducere
Aceast parte prezint trei tehnici importante pentru proiectarea i analiza algoritmilor
eficieni: programarea dinamic (capitolul 16), algoritmii greedy (capitolul 17) i analiza
amortizat (capitolul 18). Prile anterioare au tratat alte tehnici cu aplicare foarte larg cum
ar fi divide i stpnete, randomizarea i soluii recurente. Noile tehnici sunt oarecum mai
sofisticate dar sunt eseniale pentru abordarea eficient a multor probleme de calcul. Temele
introduse n aceast parte vor reaprea ulterior n carte.
n mod tipic, programarea dinamic este folosit pentru probleme de optimizare n care
trebuie fcute un numr finit de alegeri pentru a obine o soluie optimal. Deseori, pe msur
ce facem alegerile apar subprobleme de acelai tip. Programarea dinamic este eficient atunci
cnd o subproblem dat poate aprea din mai multe mulimi pariale de alegeri; tehnica cheie
este s stocm sau s memoizm soluia fiecrei subprobleme n cazul n care aceasta reapare.
Capitolul 16 arat cum aceast idee simpl poate transforma cu uurin algoritmi exponeniali
n algoritmi polinomiali.
La fel ca algoritmii de programare dinamic, algoritmii greedy se folosesc de obicei n probleme
de optimizare n care trebuie fcute un numr de alegeri pentru a ajunge la o soluie optim.
Idea unui algoritm greedy este de a face fiecare alegere ntr-o manier optim local. Un exemplu
simplu este plata restului cu numr minim de monede: pentru a minimiza numrul de monede
necesare pentru a obine restul de la o sum dat de bani este suficient s selectm n mod
repetat moneda cu cea mai mare valoare, dar nu mai mare dect restul rmas. 1 Exist multe
astfel de probleme pentru care o abordare greedy duce la gsirea unei soluii optimale mult mai
repede dect o abordare prin programare dinamic. Totui, nu este ntotdeauna uor de stabilit
dac o abordare greedy va fi eficient. Capitolul 17 recapituleaz teoria matroizilor care poate fi
de multe ori folositoare n stabilirea unei astfel de decizii.
Analiza amortizat este un instrument pentru analiza algoritmilor care execut o secven
de operaii similare. n loc s mrginim costul secvenei de operaii, mrginind separat costul
efectiv al fiecrei operaii, o analiz amortizat poate fi folosit pentru a furniza o margine a
costului efectiv al ntregii secvene. Un motiv pentru care aceast idee poate fi eficient este c,
ntr-o secven de operaii, s-ar putea s fie imposibil ca toate operaiile individuale s poat fi
efectuate n limitele cunoscute pentru cazul cel mai defavorabil. n timp ce unele operaii sunt
costisitoare, multe altele ar putea s nu fie la fel de costisitoare, din punct de vedere al timpului de
execuie. Analiza amortizat nu este doar un instrument de analiz; ea este i un mod de gndire
referitor la proiectarea algoritmilor deoarece proiectarea unui algoritm i analiza timpului su
de execuie sunt adesea strns legate ntre ele. Capitolul 18 introduce trei modaliti echivalente
de efectuare a unei analize amortizate asupra unui algoritm.

1 Pentru a fi siguri c restul poate fi ntotdeauna pltit, presupunem c exist moned avnd valoarea egal cu

unitatea.
16 Programarea dinamic

Programarea dinamic, asemenea metodelor divide i stpnete, rezolv problemele com-


binnd soluiile unor subprobleme. (n acest context, termenul de programare se refer la o
metod tabelar i nu la scrierea codului pentru un calculator.) Dup cum am artat n capitolul
1, algoritmii divide i stpnete partiioneaz problema n subprobleme independente, rezolv
recursiv subproblemele i apoi combin soluiile lor pentru a rezolva problema iniial. Spre
deosebire de aceast abordare, programarea dinamic este aplicabil atunci cnd subproblemele
nu sunt independente, adic subproblemele au n comun sub-subprobleme. n acest context,
un algoritm de tipul divide i stpnete ar presupune mai multe calcule dect ar fi necesar
dac s-ar rezolva n mod repetat sub-subproblemele comune. Un algoritm bazat pe programare
dinamic rezolv fiecare sub-subproblem o singur dat i, apoi, memoreaz soluia acesteia ntr-
un tablou, prin aceasta evitnd recalcularea soluiei ori de cte ori respectiva sub-subproblem
apare din nou.
n general, metoda programrii dinamice se aplic problemelor de optimizare. Asemenea
probleme pot avea mai multe soluii posibile. Fiecare soluie are o valoare, iar ceea ce se dorete
este determinarea soluiei a crei valoare este optim (minim sau maxim). O asemenea soluie
se numete o soluie optim a problemei, prin contrast cu soluia optim, deoarece pot fi mai
multe soluii care realizeaz valoarea optim.
Dezvoltarea unui algoritm bazat pe programarea dinamic poate fi mprit ntr-o secven
de patru pai.

1. Caracterizarea structurii unei soluii optime.

2. Definirea recursiv a valorii unei soluii optime.

3. Calculul valorii unei soluii optime ntr-o manier de tip bottom-up.

4. Construirea unei soluii optime din informaia calculat.

Paii 13 sunt baza unei abordri de tip programare dinamic. Pasul 4 poate fi omis dac
se dorete doar calculul unei singure soluii optime. n vederea realizrii pasului 4, deseori se
pstreaz informaie suplimentar de la execuia pasului 3, pentru a uura construcia unei
soluii optimale.
Seciunile care urmeaz vor folosi metoda programrii dinamice pentru a rezolva unele
probleme de optimizare. Seciunea 16.1 abordeaz problema nmulirii unui ir de matrice printr-
un numr minim de nmuliri scalare. Pe baza acestui exemplu-problem abordat prin metoda
programrii dinamice, seciunea 16.2 trateaz dou caracteristici eseniale pe care trebuie s
le prezinte problemele pentru ca programarea dinamic s fie o tehnic de soluionare viabil.
Seciunea 16.3 arat cum poate fi determinat cel mai lung subir comun a dou iruri. n final,
seciunea 16.4 folosete programarea dinamic pentru a gsi o triangulare optim pentru un
poligon convex, problem care este surprinztor de asemntoare nmulirii unui ir de matrice.
260 Capitolul 16 Programarea dinamic

16.1. nmulirea unui ir de matrice


Primul nostru exemplu de programare dinamic este un algoritm care rezolv problema
nmulirii unui ir de matrice. Se d un ir (o secven) hA1 , A2 , . . . , An i de n matrice care
trebuie nmulite, i se doree calcularea produsului
A1 A2 An (16.1)
Expresia (16.1) se poate evalua folosind algoritmul standard de nmulire a unei perechi
de matrice ca subrutin, o dat ce expresia a fost parantezat (parantezarea este necesar
pentru a rezolva toate ambiguitile privind nmulirile de matrice). Un produs de matrice este
complet parantezat fie dac este format dintr-o unic matrice, fie dac este produsul a dou
produse de matrice care sunt la rndul lor complet parantezate. Cum nmulirea matricelor
este asociativ, toate parantezrile conduc la acelai produs. De exemplu, dac irul de matrice
este hA1 , A2 , A3 , A4 i, produsul A1 A2 A3 A4 poate fi complet parantezat n cinci moduri distincte,
astfel:
(A1 (A2 (A3 A4 ))), (A1 ((A2 A3 )A4 )), ((A1 A2 )(A3 A4 )), ((A1 (A2 A3 ))A4 ), (((A1 A2 )A3 )A4 ).
Modul n care parantezm un ir de matrice poate avea un impact dramatic asupra costului
evalurii produsului. S considerm mai nti costul nmulirii a dou matrice. Algoritmul
standard este dat de urmtoarea procedur, descris n pseudocod. Prin linii i coloane sunt
referite numrul de linii, respectiv de coloane ale matricei.
nmulire-Matrice(A, B)
1: dac coloane[A] 6= linii[B] atunci
2: mesaj de eroare: dimensiuni incompatibile
3: altfel
4: pentru i 1, linii[A] execut
5: pentru j 1, coloane[B] execut
6: C[i, j] 0
7: pentru k 1, coloane[A] execut
8: C[i, j] C[i, j] + A[i, k] B[k, j]
9: returneaz C

Dou matrice A i B se pot nmuli numai dac numrul de coloane din A este egal cu
numrul de linii din B. Astfel, dac A este o matrice avnd dimensiunea p q i B este o matrice
avnd dimensiunea q r, matricea produs C este o matrice avnd dimensiunea p r. Timpul
necesar calculului matricei C este determinat de numrul de nmuliri scalare (a se vedea linia
8 din algoritm) care este pqr. n cele ce urmeaz, vom exprima timpii de execuie n funcie de
numrul de nmuliri scalare.
Pentru a ilustra modul n care apar costuri diferite la parantezri diferite ale produsului
de matrice, s considerm problema irului hA1 , A2 , A3 i de trei matrice. S presupunem c
dimensiunile matricelor sunt 10 100, 100 5 i, respectiv, 5 50. Dac efectum nmulirle
conform parantezrii ((A1 A2 )A3 ), atunci vom avea 10 100 5 = 5000 nmuliri scalare pentru
a calcula matricea A1 A2 de dimensiune 10 5, plus alte 10 5 50 = 2500 nmuliri scalare
pentru a nmuli aceast matrice cu matricea A3 . Astfel rezult un total de 7500 nmuliri
16.1. nmulirea unui ir de matrice 261

scalare. Dac, n schimb, vom efectua nmulirile conform parantezrii (A1 (A2 A3 )), vom avea
100 5 50 = 25.000 nmuliri scalare pentru a a calcula matricea A2 A3 de dimensiuni 100 50,
plus alte 10 100 50 = 50.000 nmuliri scalare pentru a nmuli A1 cu aceast matrice. Astfel
rezult un total de 75.000 nmuliri scalare. Deci, calculnd produsul conform primei parantezri,
calculul este de 10 ori mai rapid.
Problema nmulirii irului de matrice poate fi enunat n urmtorul mod: dndu-se
un ir hA1 , A2 , . . . , An i de n matrice, unde, pentru i = 1, 2, . . . , n, matricea Ai are dimensiunile
pi1 pi , s se parantezeze complet produsul A1 A2 An , astfel nct s se minimizeze numrul
de nmuliri scalare.

Evaluarea numrului de parantezri


nainte de a rezolva problema nmulirii irului de matrice prin programare dinamic, trebuie
s ne convingem c verificarea exhaustiv a tuturor parantezrilor nu conduce la un algoritm
eficient. Fie P (n) numrul de parantezri distincte ale unei secvene de n matrice. Deoarece
secvena de matrice o putem diviza ntre matricele k i (k +1), pentru orice k = 1, 2, . . . , n1, i,
apoi, putem descompune n paranteze, n mod independent, fiecare dintre cele dou subsecvene,
obinem recurena:

1 dac n = 1,
P (n) = P
n1
P (k)P (n k) dac n 2.
k=1

Problema 13-4 a cerut s se demonstreze c soluia acestei recurene este secvena de numere
Catalan:
P (n) = C(n 1),
unde

1 2n
C(n) = = (4n /n3/2 ).
n+1 n
Numrul de soluii este, deci, exponenial n n, i metoda forei brute a cutrii exhaustive este,
prin urmare, o strategie slab de determinare a modalitii de parantezare a irului de matrice.

Structura unei parantezri optime


Primul pas din schema general a metodei programrii dinamice const n caracterizarea
structurii unei soluii optimale. Pentru problema nmulirii irului de matrice, aceasta este
descris n continuare. Pentru simplitate, vom adopta convenia de notare Ai..j pentru matricea
care rezult n urma evalurii produsului Ai Ai+1 Aj . O parantezare optim a produsului
A1 A2 An mparte produsul ntre Ak i Ak+1 pentru un anumit ntreg k din intervalul
1 k < n. Aceasta nseamn c, pentru o valoare a lui k, mai nti calculm matricele A1..k i
Ak+1..n i, apoi, le nmulim pentru a produce rezultatul final A1..n . Costul acestei parantezri
optime este, deci, costul calculului matricei A1..k , plus costul calculului matricei Ak+1..n , plus
costul nmulirii celor dou matrice.
Observaia cheie este c parantezarea subirului prefix A1 A2 Ak , n cadrul parantez-
rii optime a produsului A1 A2 An , trebuie s fie o parantezare optim pentru A1 A2 Ak .
262 Capitolul 16 Programarea dinamic

De ce? Dac ar fi existat o modalitate mai puin costisitoare de parantezare a lui A1 A2 Ak ,


nlocuirea respectivei parantezri n parantezarea lui A1 A2 An ar produce o alt parantezare
pentru A1 A2 An , al crei cost ar fi mai mic dect costul optimului, ceea ce este o contradicie.
O observaie asemntoare este valabil i pentru parantezarea subirului Ak+1 Ak+2 An n
cadrul parantezrii optime a lui A1 A2 An : aceasta trebuie s fie o parantezare optim pentru
Ak+1 Ak+2 An .
Prin urmare, o soluie optim a unei instane a problemei nmulirii irului de matrice conine
soluii optime pentru instane ale subproblemelor. Existena substructurilor optime n cadrul
unei soluii optime este una dintre caracteristicile cadrului de aplicare a metodei programrii
dinamice, aa cum se va arta n seciunea 16.2.

O soluie recursiv
Al doilea pas n aplicarea metodei programrii dinamice este definirea valorii unei soluii
optime n mod recursiv, n funcie de soluiile optime ale subproblemelor. n cazul problemei
nmulirii irului de matrice, o subproblem const n determinarea costului minim al unei
parantezri a irului Ai Ai+1 Aj , pentru 1 i j n. Fie m[i, j] numrul minim de nmuliri
scalare necesare pentru a calcula matricea Ai..j ; costul modalitii optime de calcul a lui A1..n
va fi, atunci, m[1, n].
Putem defini m[i, j] n mod recursiv, dup cum urmeaz. Dac i = j, irul const dintr-o
singur matrice Ai..i = Ai i, pentru calculul produsului nu este necesar nici o nmulire scalar.
Atunci, m[i, i] = 0 pentru i = 1, 2, . . . , n. Pentru a calcula m[i, j] cnd i < j, vom folosi structura
unei soluii optimale gsite la pasul 1. S presupunem c descompunerea optim n paranteze
mparte produsul Ai Ai+1 Aj ntre Ak i Ak+1 , cu i k < j. Atunci, m[i, j] este egal cu
costul minim pentru calculul subprodusului Ai..k i Ak+1..j plus costul nmulirii acestor dou
matrice rezultat. Deoarece evaluarea produsului Ai..k Ak+1..j necesit pi1 pk pj nmuliri scalare,
vom obine
m[i, j] = m[i, k] + m[k + 1, j] + pi1 pk pj .
Aceast ecuaie recursiv presupune cunoaterea valorii lui k, lucru care nu este posibil.
Exist doar j i valori posibile pentru k, i anume k = i, i + 1, . . . , j 1. Deoarece parantezarea
optim trebuie s foloseasc una dintre aceste valori pentru k, va trebui s le verificm pe toate
pentru a o putea gsi pe cea mai bun. Atunci, definiia recursiv a costului minim a parantezrii
produsului Ai Ai+1 Aj devine
(
0 dac i = j,
m[i, j] = min {m[i, k] + m[k + 1, j] + pi1 pk pj } dac i < j. (16.2)
ik<j

Valorile m[i, j] exprim costul soluiilor optime ale subproblemelor. Pentru a putea urmri
modul de construcie a soluiei optime, s definim s[i, j] care va conine valoarea k pentru care
mprirea produsului Ai Ai+1 Aj produce o parantezare optim. Aceasta nseamn c s[i, j]
este egal cu valoarea k pentru care m[i, j] = m[i, k] + m[k + 1, j] + pi1 pk pj .

Calculul costului optimal


n acest moment, este uor s scriem un algoritm recursiv bazat pe recurena (16.2) care
calculeaz costul minim m[1, n] al produsului A1 A2 An . Dup cum vom vedea n seciunea
16.1. nmulirea unui ir de matrice 263

16.2, acest algoritm necesit un timp exponenial nu mai bun dect metoda forei brute folosit
pentru verificarea fiecrui mod de descompunere n paranteze a produsului de matrice.
Observaia important care se impune n acest moment este c avem relativ puine subpro-
bleme:
o problem pentru fiecare alegere a lui i i j ce satisfac 1 i j n, adic un total
de n2 + n = (n2 ). Un algoritm recursiv poate ntlni fiecare subproblem de mai multe ori pe
ramuri diferite ale arborelui su de recuren. Acest proprietate de suprapunere a subproble-
melor este a doua caracteristic a programrii dinamice.
n loc s calculm recursiv soluia recurenei (16.2), vom aplica cel de-al treilea pas al
schemei generale a metodei programrii dinamice i vom calcula costul optimal cu o abordare
bottom-up. Algoritmul urmtor presupune c matricea Ai are dimensiunile pi1 pi pentru
i = 1, 2, . . . , n. Intrarea este secvena hp0 , p1 , . . . , pn i, unde lungime[p] = n + 1. Procedura
folosete un tablou auxiliar m[1..n, 1..n] pentru costurile m[i, j] i un tablou auxiliar s[1..n, 1..n]
care nregistreaz acea valoare a lui k pentru care s-a obinut costul optim n calculul lui m[i, j].
Ordine-ir-Matrice(p)
1: n lungime[p] 1
2: pentru i 1, n execut
3: m[i, i] 0
4: pentru l 2, n execut
5: pentru i 1, n l + 1 execut
6: j i+l1
7: m[i, j]
8: pentru k i, j 1 execut
9: q m[i, k] + m[k + 1, j] + pi1 pk pj
10: dac q < m[i, j] atunci
11: m[i, j] q
12: s[i, j] k
13: returneaz m, s

Algoritmul completeaz tabloul m ntr-un mod ce corespunde rezolvrii problemei parantez-


rii unor iruri de matrice de lungime din ce n ce mai mare. Ecuaia (16.2) arat c m[i, j], costul
de calcul al produsului irului de j i + 1 matrice, depinde doar de costurile calculrii produselor
irurilor de mai puin de j i + 1 matrice. Aceasta nseamn c, pentru k = i, i + 1, . . . , j 1,
matricea Ai..k este un produs de k i + 1 < j i + 1 matrice, iar matricea Ak+1..j este un produs
de j k < j i + 1 matrice.
Algoritmul iniializeaz, mai nti, m[i, i] 0 pentru i = 1, 2, . . . , n (costul minim al irurilor
de lungime 1) n liniile 23. Se folosete, apoi, recurena (16.2) pentru a calcula m[i, i + 1] pentru
i = 1, 2, . . . , n 1 (costul minim al irurilor de lungime 2) la prima execuie a ciclului din liniile
412. La a doua trecere prin ciclu, se calculeaz m[i, i + 2] pentru i = 1, 2, . . . , n 2 (costul
minim al irurilor de lungime 3) etc. La fiecare pas, costul m[i, j] calculat pe liniile 912 depinde
doar de intrrile m[i, k] i m[k + 1, j] ale tabloului, deja calculate.
Figura 16.1 ilustreaz aceast procedur pe un ir de n = 6 matrice. Deoarece am definit
m[i, j] doar pentru i j, din tabloul m folosim doar poriunea situat strict deasupra diagonalei
principale. Figura arat tablourile rotite astfel nct diagonala principal devine orizontal, iar
irul de matrice este nscris de-a lungul liniei de jos. Folosind acest model, costul minim m[i, j] de
nmulire a subirului Ai Ai+1 Aj de matrice poate fi gsit la intersecia liniilor care pornesc
264 Capitolul 16 Programarea dinamic

Figura 16.1 Tabelele m i s calculate de Ordine-ir-Matrice pentru n = 6 i matricele cu dimen-


siunile date mai jos:
matrice dimensiuni
A1 30 35
A2 35 15
A3 15 5
A4 5 10
A5 10 20
A6 20 25
Tabelele sunt rotite astfel nct diagonala principal devine orizontal. n tabloul m sunt utilizate doar
elementele de deasupra diagonalei principale, iar n tabloul s sunt utilizate doar elementele de sub
diagonala principal. Numrul minim de nmuliri scalare necesare pentru nmulirea a ase matrice este
m[1, 6] = 15.125. Dintre ptratele haurate cu gri deschis, perechile care sunt colorate cu aceeai nuan
sunt considerate mpreun n linia 9, cnd calculm

m[2, 2] + m[3, 5] + p1 p2 p5 = 0 + 2500 + 35 15 20 = 13000
m[2, 5] = min m[2, 3] + m[4, 5] + p1 p3 p5 = 2625 + 1000 + 35 5 20 = 7125 = 7125.

m[2, 4] + m[5, 5] + p1 p4 p5 = 4375 + 0 + 35 10 20 = 11375

pe direcia nord-est din Ai i pe direcia nord-vest din Aj . Fiecare rnd orizontal din tablou
conine valorile pentru iruri de matrice de aceeai lungime. Procedura Ordine-ir-Matrice
calculeaz rndurile de jos n sus i de la stnga la dreapta n cadrul fiecrui rnd. O valoare
m[i, j] este calculat pe baza folosirii produselor pi1 pk pj pentru k = i, i+1, . . . , j 1 i a tuturor
valorilor aflate pe direcia sud-est i sud-vest fa de m[i, j].
O simpl examinare a structurii de ciclu imbricat din Ordine-ir-Matrice conduce la
constatarea c timpul de execuie a algoritmului este O(n3 ). n fiecare dintre cele trei cicluri
imbricate, indicii acestora (l, i i k) iau cel mult n valori. Exerciiul 16.1-3 cere s se demonstreze
c timpul de execuie al acestui algoritm este (n3 ). Algoritmul necesit un spaiu (n2 ) pentru
a stoca tablourile m i s. De aceea, algoritmul Ordine-ir-Matrice este mult mai eficient
dect metoda de enumerare a tuturor variantelor de parantezare a produsului de matrice i de
verificare a acestora.
16.1. nmulirea unui ir de matrice 265

Construirea unei soluii optime


Dei algoritmul Ordine-ir-Matrice determin numrul optim de nmuliri scalare
necesare pentru calculul produsului irului de matrice, acesta nu prezint n mod direct, cum
trebuie fcut nmulirea. Pasul 4 al schemei generale a metodei programrii dinamice urmrete
construirea unei soluii optime din informaia disponibil.
n acest caz particular, vom folosi tabloul s[1..n, 1..n] pentru a determina modul optim de
nmulire a matricelor. Fiecare element s[i, j] conine valoarea lui k pentru care parantezarea
optim a produsului Ai Ai+1 Aj mparte produsul ntre Ak i Ak+1 . Atunci tim c, n produsul
final de calcul al matricei A1..n , optimul este A1..s[1,n] As[1,n]+1..n . nmulirile anterioare pot fi
determinate recursiv, deoarece s[1, s[1, n]] determin ultima nmulire matriceal din calculul
lui A1..s[1,n] i s[s[1, n] + 1, n] determin ultima nmulire matriceal din calculul lui As[1,n]+1..n .
Urmtoarea procedur recursiv calculeaz produsul irului de matrice Ai..j , fiind date matricele
A = hA1 , A2 , . . . , An i, tabloul s calculat de Ordine-ir-Matrice i indicii i i j. Apelul iniial
este nmulire-ir-Matrice(A,s,1,n).
nmulire-ir-Matrice(A,s,i,j)
1: dac j > i atunci
2: X nmulire-ir-Matrice(A, s, i, s[i, j])
3: Y nmulire-ir-Matrice(A, s, s[i, j] + 1, j)
4: returneaz nmulire-Matrice(X, Y )
5: altfel
6: returneaz Ai
n exemplul din figura 16.1, apelul nmulire-ir-Matrice(A,s,1,6) calculeaz produsul
irului de matrice conform descompunerii n paranteze
((A1 (A2 A3 ))((A4 A5 )A6 )). (16.3)

Exerciii
16.1-1 Gsii o parantezare optim a produsului unui ir de matrice al crui ir de dimensiuni
este h5, 10, 3, 12, 5, 50, 6i.

16.1-2 Proiectai un algoritm eficient Scrie-Optim-Prini pentru a afia parantezarea


optim a unui ir de matrice dat de tabloul s calculat de Ordine-ir-Matrice. Analizai
algoritmul.

16.1-3 Fie R(i, j) numrul de accesri ale elementului m[i, j] din tabloul m, de ctre algoritmul
Ordine-ir-Matrice, pentru calcularea celorlalte elemente ale tabloului. Artai c, pentru
ntregul tablou, numrul total de accesri este
n X
X n
n3 n
R(i, j) = .
i=1 j=i
3
Pn
(Indicaie: Identitatea i=1 i2 = n(n + 1)(2n + 1)/6 poate fi util.)

16.1-4 Artai c o parantezare complet a unei expresii cu n elemente are exact n 1 perechi
de paranteze.
266 Capitolul 16 Programarea dinamic

16.2. Elemente de programare dinamic


Cu toate c am prezentat un exemplu de aplicare a metodei programrii dinamice, este
posibil s existe, n continuare, ntrebri asupra situaiilor n care ea este aplicabil, sau, altfel
spus, cnd trebuie cutat o soluie de programare dinamic pentru o anumit problem?
n aceast seciune se vor examina dou componente de baz pe care trebuie s le prezinte
problema de optimizare pentru ca programarea dinamic s fie aplicabil: substructura optim
i subproblemele suprapuse. Se va urmri, ns, i o variant a metodei, numit memoizare, n
care se utilizeaz proprietatea de suprapunere a subproblemelor.

Substructura optim
Primul pas al rezolvrii unei probleme de optimizare prin programare dinamic const n
caracterizarea structurii unei soluii optime. Spunem c problema prezint o substructur
optim dac o soluie optim a problemei include soluii optime ale subproblemelor. Ori de
cte ori o problem prezint o structur optim, acesta este un bun indiciu pentru posibilitatea
aplicrii programrii dinamice. (De asemenea, aceasta nseamn c se pot, totui, aplica i
strategii greedy; a se vedea capitolul 17).
n seciunea 16.1 am vzut c problema nmulirii irului de matrice prezint o substruc-
tur optim. Am observat c o parantezare optim pentru A1 A2 An , care separ produsul
ntre Ak i Ak+1 , include soluii optime pentru problemele parantezrii matricelor A1 A2 Ak
i Ak+1 Ak+2 An . Tehnica utilizat pentru a arta c subproblemele au soluii optime este
clasic. Presupunem c exist o soluie mai bun pentru o subproblem i artm c aceast
presupunere contrazice optimalitatea soluiei problemei iniiale.
Substructura optim a unei probleme sugereaz, deseori, un spaiu potrivit al subpro-
blemelor pentru care se poate aplica programarea dinamic. De obicei, exist mai multe
clase de subprobleme care pot fi considerate naturale pentru o problem. De exemplu,
spaiul subproblemelor pe care le-am considerat la nmulirea irului de matrice coninea toate
subsecvenele irului de intrare. La fel de bine, am fi putut alege ca spaiu al subproblemelor
secvene arbitrare de matrice din irul de intrare, dar acest spaiu al subproblemelor ar fi fost
prea mare. Un algoritm de programare dinamic bazat pe acest spaiu al subproblemelor ar
rezolva mult mai multe probleme dect ar fi necesar.
Investigarea substructurii optime a unei probleme prin iterarea instanelor subproblemelor
acesteia este o metod bun pentru a gsi un spaiu potrivit de subprobleme pentru programarea
dinamic. De exemplu, dup examinarea structurii unei soluii optime a problemei nmulirii
irului de matrice, putem itera i examina structura soluiilor optime ale subproblemelor, a sub-
subproblemelor i aa mai departe. Descoperim, astfel, c toate subproblemele sunt compuse din
subsecvene ale irului hA1 , A2 , . . . , An i. Deci, mulimea irurilor de forma hAi , Ai+1 , . . . , Aj i cu
1 i j n este un spaiu de subprobleme natural i rezonabil de utilizat.

Suprapunerea subproblemelor
O a doua component pe care trebuie s o aib o problem de optimizare pentru ca
programarea dinamic s fie aplicabil este ca spaiul subproblemelor s fie restrns, n sensul c
un algoritm recursiv rezolv mereu aceleai subprobleme, n loc s genereze subprobleme noi. De
16.2. Elemente de programare dinamic 267

Figura 16.2 Arborele de recuren pentru calculul apelului ir-Matrice-Recursiv(p, 1, 4). Fiecare
nod conine parametrii i i j. Calculele efectuate n subarborii haurai sunt nlocuite de apariia unui
tablou de echivalen n ir-Matrice-Memorat(p, 1, 4).

obicei, numrul total de subprobleme distincte este dependent polinomial de dimensiunea datelor
de intrare. Cnd un algoritm recursiv abordeaz mereu o aceeai problem, se spune c problema
de optimizare are subprobleme suprapuse. Spre deosebire de aceasta, o problem care se
rezolv cu un algoritm de tip divide i stpnete genereaz, la fiecare nou etap, probleme
noi. n general, algoritmii de programare dinamic folosesc suprapunerea subproblemelor prin
rezolvarea o singur dat a fiecrei subprobleme, urmat de stocarea soluiei ntr-un tablou unde
poate fi regsit la nevoie, necesitnd pentru regsire un timp constant.
Pentru a ilustra proprietatea de subprobleme suprapuse, vom reexamina problema nmulirii
irului de matrice. Revenind la figura 16.1, observm c algoritmul Ordine-ir-Matrice preia,
n mod repetat, soluiile subproblemelor din liniile de jos atunci cnd rezolv subproblemele din
liniile superioare. De exemplu, valoarea m[3, 4] este referit de patru ori: n timpul calculelor
pentru m[2, 4], m[1, 4], m[3, 5] i m[3, 6]. Dac m[3, 4] ar fi recalculat de fiecare dat n loc s fie
preluat din tablou, creterea timpului de execuie ar fi dramatic. Pentru a vedea aceasta, s
considerm urmtoarea procedur recursiv (ineficient) care determin m[i, j], numrul minim
de nmuliri scalare necesare pentru a calcula produsul irului de matrice Ai..j = Ai Ai+1 . . . Aj .
Procedura este bazat direct pe recurena (16.2).

ir-Matrice-Recursiv(p, i, j)
1: dac i = j atunci
2: returneaz 0
3: m[i, j]
4: pentru k i, j 1 execut
5: q ir-Matrice-Recursiv(p, i, k) + ir-Matrice-Recursiv(p, k + 1, j) + pi1 pk pj
6: dac q < m[i, j] atunci
7: m[i, j] q
8: returneaz m[i, j]

Figura 16.2 prezint arborele de recuren produs de apelul ir-Matrice-Recursiv(p,1,4).


Fiecare nod este etichetat cu valorile parametrilor i i j. Se observ c anumite perechi de valori
apar de mai multe ori.
268 Capitolul 16 Programarea dinamic

De fapt, putem arta c timpul de execuie T (n) necesar pentru calculul lui m[1, n] prin
aceast procedur recursiv este cel puin exponenial n n. S presupunem c executarea liniilor
12 i a liniilor 67 ia cel puin un timp egal cu unitatea. Inspectarea procedurii conduce la
recurena

T (1) 1,
n1
X
T (n) 1+ (T (k) + T (n k) + 1), pentru n > 1.
k=1

S observm c pentru i = 1, 2, . . . , n 1, fiecare termen T (i) apare o dat ca T (k) i o dat ca


T (n k); adunnd cele n 1 uniti cu unitatea din primul termen al sumei, recurena se poate
rescrie ca
n1
X
T (n) 2 T (i) + n. (16.4)
i=1

Vom arta c T (n) = (2n ) folosind inducia matematic. Mai precis, vom arta c T (n)
n1
2 pentru orice n 1. Pentru n = 1, este clar c T (1) 1 = 20 . Prin inducie, pentru n 2
avem
n1
X n2
X
T (n) 2 2i1 + n = 2 2i + n = 2(2n1 1) + n = (2n 2) + n 2n1 ,
i=1 i=0

ceea ce completeaz demonstraia. Atunci, totalul calculelor realizate de apelul ir-Matrice-


Recursiv(p, 1, n) este cel puin exponenial n n.
Comparai acest algoritm recursiv, top-down, cu algoritmul de programare dinamic
bottom-up. Acesta din urm este mult mai eficient deoarece folosete proprietatea de
suprapunere a subproblemelor. Problema are exact (n2 ) subprobleme distincte, i algoritmul
de programare dinamic o rezolv pe fiecare o singur dat. Pe de alt parte, algoritmul recursiv
trebuie s rezolve n mod repetat fiecare subproblem, ori de cte ori apare n arborele de
recuren. Se poate ncerca aplicarea programrii dinamice ori de cte ori arborele de recuren
corespunztor soluiei recursive naturale conine, n mod repetat, o aceeai subproblem, iar
numrul total de subprobleme este mic.

Memoizarea
Vom prezenta n continuare o variant a programrii dinamice, care mrete, deseori, eficiena
abordrii uzuale a programrii dinamice, folosind n acelai timp o strategie top-down. Ideea
este de a memoiza algoritmul recursiv natural, dar despre care am artat c este ineficient. Ca
i n cazul programrii dinamice obinuite, soluiile subproblemelor se pstreaz ntr-un tablou,
dar structura de control pentru completarea tabloului este mult mai asemntoare algoritmului
recursiv.
Un algoritm recursiv memoizat folosete un element al tabloului pentru fiecare soluie a
fiecrei subprobleme. Fiecare element al tabloului conine, la nceput, o valoare special care
indic faptul c respectivul element trebuie completat. Atunci cnd subproblema este ntlnit
prima oar pe parcursul execuiei algoritmului recursiv, soluia sa este calculat i apoi stocat
16.2. Elemente de programare dinamic 269

n tablou. Dup aceasta, ori de cte ori este ntlnit subproblema respectiv, valoarea stocat
n tablou este cutat i regsit.1
Procedura urmtoare este versiunea memoizat a procedurii ir-Matrice-Recursiv.
ir-Matrice-Memoizat(p)
1: n lungime[p] 1
2: pentru i 1, n execut
3: pentru j i, n execut
4: m[i, j]
5: returneaz ir-Echivalent(p, 1, n)

ir-Echivalent(p, i, j)
1: dac m[i, j] < atunci
2: returneaz m[i, j]
3: dac i = j atunci
4: m[i, j] 0
5: altfel
6: pentru k i, j 1 execut
7: q ir-Echivalent(p, i, k) + ir-Echivalent(p, k + 1, j) + pi1 pk pj
8: dac q < m[i, j] atunci
9: m[i, j] q
10: returneaz m[i, j]

Algoritmul ir-Matrice-Memoizat, la fel ca i Ordine-ir-Matrice, utilizeaz tabloul


m[1..n, 1..n] al valorilor calculate pentru m[i, j], numrul minim de nmuliri scalare necesare
pentru a calcula matricea Ai..j . Fiecare element al tabloului conine, la nceput, elementul
pentru a arta c respectivul element trebuie determinat. Atunci cnd se execut apelul ir-
Echivalent(p, i, j), dac m[i, j] < , pe linia 1, procedura se rezum la a returna costul
deja calculat m[i, j] (linia 2). Altfel, costul este calculat la fel ca n algoritmul ir-Matrice-
Recursiv, memorat n m[i, j] i returnat. (Valoarea este convenabil pentru marcarea
elementelor necalculate ale tabloului, deoarece este valoarea folosit la iniializarea valorii
m[i, j] n linia 3 din ir-Matrice-Recursiv.) Atunci, ir-Echivalent(p, i, j) returneaz,
ntotdeauna, valoarea m[i, j], dar o calculeaz efectiv numai n cazul primului apel avnd
parametrii i i j.
Figura 16.2 ilustreaz modul n care algoritmul ir-Matrice-Memoizat economisete timp
n raport cu ir-Matrice-Recursiv. Subarborii haurai reprezint valori cutate n tablou i
care nu sunt calculate.
Asemntor algoritmului de programare dinamic Ordine-ir-Matrice, procedura ir-
Matrice-Memoizat are timpul de execuie O(n3 ). Fiecare dintre cele (n2 ) elemente ale
tabloului este iniializat o singur dat n linia 4 a procedurii ir-Matrice-Memoizat i
completat cu valoarea definitiv printr-un singur apel al procedurii ir-Echivalent. Fiecare
dintre aceste (n2 ) apeluri dureaz un timp O(n), fr a lua n considerare timpul necesar
calculrii celorlalte elemente ale tabloului, deci, n total, este folosit un timp O(n3 ). Prin urmare,
memoizarea transform un algoritm (2n ) ntr-un algoritm O(n3 ).
1 Aceast abordare presupune c mulimea parametrilor tuturor subproblemelor posibile este cunoscut i c

este stabilit relaia dintre poziiile din tablou i subprobleme. O alt abordare presupune memorarea indexat
(hashing), folosind parametrii subproblemelor drept chei de cutare.
270 Capitolul 16 Programarea dinamic

n concluzie, problema nmulirii irului de matrice se poate rezolva n timp O(n3 ) fie printr-
un algoritm top-down cu memoizare, fie printr-un algoritm de programare dinamic bottom-
up. Ambele metode folosesc proprietatea subproblemelor suprapuse. n total exist numai
(n2 ) subprobleme distincte i fiecare dintre metodele amintite rezolv fiecare subproblem o
singur dat. Fr memoizare, algoritmul recursiv natural necesit un timp exponenial, deoarece
subproblemele sunt rezolvate n mod repetat.
n practic, dac toate subproblemele trebuie rezolvate cel puin o dat, un algoritm de
programare dinamic bottom-up mbuntete cu un factor constant un algoritm top-
down cu memoizare, deoarece nu apare efortul suplimentar necesitat de recuren, iar pentru
gestionarea tabloului, efortul suplimentar este mai mic. Mai mult chiar, exist probleme pentru
care modul regulat de accesare a tabloului n metoda programrii dinamice poate fi folosit pentru
a reduce suplimentar timpul sau spaiul necesar. Reciproc, dac unele subprobleme din spaiul
subproblemelor nu trebuiesc rezolvate deloc, soluia cu memoizare are avantajul de a rezolva
numai subproblemele necesare.

Exerciii
16.2-1 Comparai recurena (16.4) cu recurena (8.4), aprut n analiza timpului mediu de
execuie al algoritmului de sortare rapid. Explicai, intuitiv, de ce soluiile celor dou recurene
sunt att de diferite.

16.2-2 Care este modul cel mai eficient de determinare a numrului optim de nmuliri n
problema produsului de matrice: enumerarea tuturor parantezrilor posibile ale produsului
i calculul numrului de nmuliri pentru fiecare descompunere, sau execuia procedurii ir-
Matrice-Recursiv? Justificai rspunsul.

16.2-3 Desenai arborele de recuren pentru procedura Sorteaz-Prin-Interclasare,


descris n seciunea 1.3.1, pentru un vector de 16 elemente. Explicai de ce memoizarea este
ineficient pentru accelerarea unui algoritm bun de tip divide i stpnete, aa cum este
Sorteaz-Prin-Interclasare.

16.3. Cel mai lung subir comun


Urmtoarea problem pe care o vom lua n considerare este problema celui mai lung subir
comun. Un subir al unui ir dat este irul iniial din care lipsesc unele elemente (eventual nici
unul). n mod formal, dndu-se irul X = hx1 , x2 , . . . , xm i, un alt ir Z = hz1 , z2 , . . . , zk i este un
subir al lui X dac exist un ir strict cresctor de indici din X, hi1 , i2 , . . . , ik i, astfel nct,
pentru toate valorile j = 1, 2, . . . , k, avem xij = zj . De exemplu, Z = hB, C, D, Bi este un subir
al lui X = hA, B, C, B, D, A, Bi, secvena de indici corespunztoare fiind h2, 3, 5, 7i.
Dndu-se dou iruri X i Y , spunem c irul Z este un subir comun pentru X i Y dac
Z este un subir att pentru X ct i pentru Y. De exemplu, dac X = hA, B, C, B, D, A, Bi
i Y = hB, D, C, A, B, Ai, irul hB, C, Ai este un subir comun pentru X i Y . irul hB, C, Ai
nu este cel mai lung subir comun (CMLSC) pentru X i Y , deoarece are lungimea 3, iar irul
hB, C, B, Ai, care este de asemenea subir comun lui X i Y , are lungimea 4. irul hB, C, B, Ai
16.3. Cel mai lung subir comun 271

este un CMLSC pentru X i Y , la fel i irul hB, D, A, Bi, deoarece nu exist un subir comun
de lungime cel puin 5.
n problema celui mai lung subir comun, se dau dou iruri X = hx1 , x2 , . . . , xm i i
Y = hy1 , y2 , . . . , yn i i se dorete determinarea unui subir comun de lungime maxim pentru
X i Y . Aceast seciune va arta c problema CMLSC poate fi rezolvat eficient prin metoda
programrii dinamice.

Caracterizarea celui mai lung subir comun


O abordare prin metoda forei brute pentru rezolvarea problemei CMLSC const n
enumerarea tuturor subirurilor lui X i verificarea dac acestea constituie un subir i pentru
Y , memornd cel mai lung subir gsit. Fiecare subir al lui X corespunde unei submulimi a
indicilor lui X, h1, 2, . . . , mi. Exist 2m subiruri pentru X i, deci, aceast abordare necesit un
timp exponenial, ceea ce o face inabordabil pentru iruri de lungimi mari.
Problema CMLSC are proprietatea de substructur optim, aa cum vom arta n urmtoarea
teorem. Clasa natural de subprobleme corespunde unor perechi de prefixe ale celor dou iruri
de intrare. Mai precis, dndu-se un ir X = hx1 , x2 , . . . , xm i, definim prefixul i al lui X, pentru
i = 0, 1, . . . , m, ca fiind Xi = hx1 , x2 , . . . , xi i. De exemplu, dac X = hA, B, C, B, D, A, Bi,
atunci X4 = hA, B, C, Bi iar X0 este irul vid.

Teorema 16.1 (Substructura optimal a unui CMLSC) Fie irurile X = hx1 , x2 , . . . ,


xm i i Y = hy1 , y2 , . . . , yn i i fie Z = hz1 , z2 , . . . , zk i un CMLSC pentru X i Y .

1. Dac xm = yn , atunci zk = xm = yn i Zk1 este un CMLSC pentru Xm1 i Yn1 .

2. Dac xm 6= yn , atunci, din zk 6= xm rezult c Z este un CMLSC pentru Xm1 i Y .

3. Dac xm 6= yn , atunci, din zk 6= yn rezult c Z este un CMLSC pentru X i Yn1 .

Demonstraie. (1) Dac zk 6= xm , atunci putem aduga xm = yn la Z pentru a obine un


subir comun a lui X i Y de lungime k + 1, contrazicnd presupunerea c Z este cel mai lung
subir comun pentru X i Y . Deci, va trebui s avem zk = xm = yn . Prefixul Zk1 este un subir
comun de lungime k 1 pentru Xm1 i Yn1 . Dorim s demonstrm c este un CMLSC. S
presupunem, prin absurd, c exist un subir W comun pentru Xm1 i Yn1 , a crui lungime
este fie mai mare dect k 1. Atunci, adugnd la W elementul xm = yn , se va forma un subir
comun a lui X i Y a crui lungime este mai mare dect k, ceea ce este o contradicie.
(2) Dac zk 6= xm , atunci Z este un subir comun pentru Xm1 i Y . Dac ar exista un subir
comun W al lui Xm1 i Y , cu lungime mai mare dect k, atunci W ar fi i un subir comun al
lui Xm i Y , contrazicnd presupunerea c Z este un CMLSC pentru X i Y .
(3) Demonstraia este simetric celei de la (2).
Caracterizarea din teorema 16.1 arat c un CMLSC al dou iruri conine un CMLSC pentru
prefixele celor dou iruri. Atunci, problema CMLSC are proprietatea de substructur optimal.
O soluie recursiv are, de asemenea, proprietatea de suprapunere a problemelor, dup cum vom
arta n cele ce urmeaz.
272 Capitolul 16 Programarea dinamic

O soluie recursiv a subproblemelor


Teorema 16.1 implic faptul c exist fie una, fie dou probleme care trebuie examinate
pentru gsirea unui CMLSC pentru X = hx1 , x2 , . . . , xm i i Y = hy1 , y2 , . . . , yn i. Dac xm = yn ,
trebuie gsit un CMLSC pentru Xm1 i Yn1 . Adugarea elementului xm = yn la acest CMLSC
produce un CMLSC pentru X i Y . Dac xm 6= yn , atunci trebuie rezolvate dou subprobleme:
gsirea unui CMLSC pentru Xm1 i Y i gsirea unui CMLSC pentru X i Yn1 . Cel mai lung
CMLSC dintre acestea dou va fi CMLSC pentru X i Y .
Se poate observa c problema CMLSC se descompune n subprobleme suprapuse. Pentru a
gsi un CMLSC al irurilor X i Y , va trebui, probabil, calculat CMLSC pentru X i Yn1 ,
respectiv, pentru Xm1 i Y . Dar fiecare dintre aceste subprobleme conine sub-subproblema
gsirii CMLSC pentru Xm1 i Yn1 . Multe alte subprobleme au n comun sub-subprobleme.
Ca i problema nmulirii irului de matrice, soluia recursiv pentru problema CMLSC
implic stabilirea unei recurene pentru costul unei soluii optime. S definim c[i, j] ca lungimea
unui CMLSC al irurilor Xi i Yj . Dac i = 0 sau j = 0, CMLSC are lungimea 0. Substructura
optimal a problemei CMLSC produce formula recursiv

0 dac i = 0 sau j = 0,
c[i, j] = c[i 1, j 1] + 1 dac i, j > 0 i xi = yj , (16.5)

max(c[i, j 1], c[i 1, j]) dac i, j > 0 i xi 6= yj .

Calculul lungimii unui CMLSC


Pe baza ecuaiei (16.5) se poate scrie un algoritm recursiv avnd timp exponenial pentru
calculul lungimii unui CMLSC a dou iruri. Deoarece exist numai (mn) subprobleme dis-
tincte, vom folosi metoda programrii dinamice pentru a calcula soluiile n mod bottom-up.
Lungime-CMLSC(X, Y )
1: m lungime[X]
2: n lungime[Y ]
3: pentru i 1, m execut
4: c[i, 0] 0
5: pentru j 0, n execut
6: c[0, j] 0
7: pentru i 1, m execut
8: pentru j 1, n execut
9: dac xi = yj atunci
10: c[i, j] c[i 1, j 1] + 1
11: b[i, j] -
12: altfel
13: dac c[i 1, j] c[i, j 1] atunci
14: c[i, j] c[i 1, j]
15: b[i, j]
16: altfel
17: c[i, j] c[i, j 1]
18: b[i, j]
19: returneaz c, b
16.3. Cel mai lung subir comun 273

Procedura Lungime-CMLSC are ca date de intrare dou iruri X = hx1 , x2 , . . . , xm i i


Y = hy1 , y2 , . . . , yn i. Procedura memoreaz valorile c[i, j] ntr-un tablou c[0..m, 0..n] ale crui
elemente sunt calculate n ordinea cresctoare a liniilor. (Aceasta nseamn c se completeaz
mai nti prima linie de la stnga la dreapta, apoi a doua linie i aa mai departe.) De asemenea,
se construiete un tablou b[1..m, 1..n] care simplific determinarea unei soluii optimale. Intuitiv,
b[i, j] indic elementul tabloului care corespunde soluiei optime a subproblemei alese la calculul
lui c[i, j]. Procedura returneaz tablourile b i c; c[m, n] conine lungimea unui CMLSC pentru
X i Y .
Figura 16.3 conine tabloul produs de Lungime-CMLSC pentru irurile X = hA , B, C,
B, D, A, Bi i Y = hB, D, C, A, B, Ai. Timpul de execuie al procedurii este O(mn), deoarece
calculul fiecrui element al tabloului necesit un timp O(1).

Construirea unui CMLSC


Tabelul b returnat de Lungime-CMLSC poate fi folosit pentru construcia rapid a unui
CMLSC pentru X = hx1 , x2 , . . . , xm i i Y = hy1 , y2 , . . . , yn i. Pur i simplu, se ncepe cu
b[m, n] i se parcurge tabloul conform direciilor indicate. Ori de cte ori se ntlnete un
element - pe poziia b[i, j], aceasta nseamn c xi = yj este un element al CMLSC. Prin
aceast metod, elementele CMLSC sunt regsite n ordine invers. Urmtoarea procedur
recursiv tiprete un CMLSC al irurilor X i Y n ordinea corect. Apelul iniial este Scrie-
CMLSC(b,X,lungime[X],lungime[Y ]).
Scrie-CMLSC(b, X, i, j)
1: dac i = 0 sau j = 0 atunci
2: revenire
3: dac b[i, j] =- atunci
4: Scrie-CMLSC(b, X, i 1, j 1)
5: tiprete xi
6: altfel dac b[i, j] = atunci
7: Scrie-CMLSC(b, X, i 1, j)
8: altfel
9: Scrie-CMLSC(b, X, i, j 1)

Pentru tabloul b din figura 16.3, aceast procedur tiprete BCBA. Procedura necesit
un timp de O(m + n), deoarece, cel puin unul dintre i i j este decrementat n fiecare etap a
recurenei.

mbuntirea codului
O dat ce s-a construit un algoritm, se descoper c, deseori, timpul de execuie sau spaiul
folosit pot fi mbuntite. Acest lucru este adevrat, mai ales, pentru programarea dinamic
clasic. Anumite modificri pot simplifica implementarea i pot mbunti factorii constani, dar
nu pot aduce o mbuntire asimptotic a performanei. Alte modificri pot aduce mbuntiri
asimptotice substaniale att pentru timpul de execuie ct i pentru spaiul ocupat. De exemplu,
se poate elimina complet tabloul b. Fiecare element c[i, j] depinde de numai trei alte elemente ale
tabloului c: c[i 1, j 1], c[i 1, j] i c[i, j 1]. Dndu-se valoarea lui c[i, j], se poate determina,
n timp O(1), care dintre aceste trei valori a fost folosit pentru calculul lui c[i, j] fr a mai folosi
274 Capitolul 16 Programarea dinamic

Figura 16.3 Tabelele c i b calculate de Lungime-CMLSC pentru irurile X = hA, B, C, B, D, A, Bi


i Y = hB, D, C, A, B, Ai. Ptratul din linia i i coloana j conine valoarea c[i, j] precum i sgeata
potrivit pentru valoarea lui b[i, j]. Valoarea 4 a lui c[7, 6] colul cel mai din dreapta jos n tablou
este lungimea unui CMLSC hB, C, B, Ai al lui X i Y . Pentru i, j > 0, valoarea c[i, j] depinde doar de
valoarea expresiei xi = yj i de valorile elementelor c[i1, j], c[i, j 1] i c[i1, j 1], care sunt calculate
naintea lui c[i, j]. Pentru a reconstrui elementele unui CMLSC, se urmresc sgeile corespunztoare lui
b[i, j] ncepnd cu colul cel mai din dreapta; drumul este haurat. Fiecare - pe acest drum corespunde
unui element (care este evideniat) pentru care xi = yj aparine unui CMLSC.

tabloul b. Ca o consecin, putem reconstrui un CMLSC n timp O(m + n) folosind o procedur


similar cu Scrie-CMLSC. (Exerciiul 16.3-2 cere algoritmul corespunztor n pseudocod.)
Dei prin aceast metod se elibereaz un spaiu (mn), spaiul auxiliar necesar calculului unui
CMLSC nu descrete asimptotic, deoarece este oricum necesar un spaiu (mn) pentru tabloul
c.
Totui, spaiul necesar pentru Lungime-CMLSC l putem reduce deoarece, la un moment
dat, sunt necesare doar dou linii ale tabloului c: linia care este calculat i linia precedent. (De
fapt, putem folosi doar puin mai mult spaiu dect cel necesar unei linii a lui c, pentru a calcula
lungimea unui CMLSC; vezi exerciiul 16.3-4.) Aceast mbuntire funcioneaz doar dac
este necesar numai lungimea unui CMLSC; dac este nevoie i de reconstruirea elementelor
unui CMLSC, tabloul mai mic nu conine destul informaie pentru a reface etapele n timp
O(m + n).

Exerciii
16.3-1 Determinai un CMLSC pentru h1, 0, 0, 1, 0, 1, 0, 1i i h0, 1, 0, 1, 1, 0, 1, 1, 0i.

16.3-2 Artai cum poate fi reconstituit un CMLSC pe baza tabloului c (completat) i a irurilor
iniiale X = hx1 , x2 , . . . , xm i i Y = hy1 , y2 , . . . , yn i n timp O(m + n), fr a folosi tabloul b.
16.4. Triangularea optim a poligoanelor 275

16.3-3 Dai o versiune cu memoizare a procedurii Lungime-CMLSC, care se execut n timp


O(mn).

16.3-4 Artai cum se poate calcula lungimea unui CMLSC folosind doar 2 min(m, n) elemente
din tabloul c i un spaiu suplimentar de O(1). Indicai apoi modul de realizare a acestui calcul
folosind doar min(m, n) elemente i un spaiu suplimentar O(1).

16.3-5 Dai un algoritm de complexitate n timp O(n2 ) care gsete cel mai lung subir monoton
cresctor al unui ir de n numere.

16.3-6 ? Scriei un algoritm cu complexitate n timp O(n lg n) care gsete cel mai lung subir
monoton cresctor al unui ir de n numere. (Indicaie: observai c ultimul element al unui subir
candidat de lungime i este cel puin la fel de mare ca ultimul element al subirului candidat de
lungime i 1. Pstrai subirurile candidate legndu-le prin secvena de intrare.)

16.4. Triangularea optim a poligoanelor


n acest paragraf vom investiga problema determinrii unei triangulri optime a unui poligon
convex. Aceast problem geometric prezint multe similariti cu problema parantezrii
produsului de matrice, chiar dac aceste asemnri nu sunt evidente.
Un poligon este o curb nchis, liniar pe poriuni, n plan. Mai explicit, este o curb
avnd captul iniial identic cu cel final i format dintr-o secven de segmente de dreapt,
numite laturi ale poligonului. Un punct care unete dou fee ale poligonului se numete
vrf . Vom presupune, n continuare, c poligonul este simplu, adic nu se auto-intersecteaz.
Mulimea de puncte din plan cuprinse de un poligon simplu formeaz interiorul poligonului,
mulimea punctelor aparinnd efectiv poligonului formeaz frontiera, iar mulimea de puncte
care nconjoar poligonul se numete exterior . Un poligon simplu este numit convex dac,
dndu-se oricare dou puncte de pe frontier sau din interiorul su, toate punctele aparinnd
segmentului care unete aceste dou puncte se afl fie pe frontier fie n interiorul poligonului.
Un poligon convex poate fi reprezentat prin precizarea vrfurilor, de exemplu n sensul
acelor de ceasornic. Adic, dac P = hv0 , v1 , . . . , vn1 i este un poligon convex, atunci cele n
laturi ale sale sunt v0 v1 , v1 v2 , . . . , vn1 vn , unde vom considera vn ca fiind v0 . (n general, vom
presupune, implicit, c toate operaiile aritmetice asupra indicilor vrfurilor poligonului sunt
efectuate modulo numrul de vrfuri.)
Dndu-se dou vrfuri neadiacente vi i vj , segmentul vi vj se numete coard a poligonului.
O coard vi vj mparte poligonul n dou poligoane: hvi , vi+1 , . . . , vj i i hvj , vj+1 , . . . , vi i.
O triangulare a poligonului este o mulime T de coarde ale poligonului care l mpart
n triunghiuri disjuncte (poligoane cu 3 laturi). Figura 16.4 prezint dou modaliti de
triangulare a unui poligon avnd 7 laturi. ntr-o triangulare, coardele nu se intersecteaz (cu
excepia capetelor lor), iar mulimea T este maximal, adic orice coard care nu aparine
mulimii T va intersecta o coard din T . Laturile triunghiurilor produse de triangulare sunt fie
coarde n triangulare, fie laturi ale poligonului. Fiecare triangulare a unui poligon convex cu n
vrfuri are n 3 coarde i mparte poligonul n n 2 triunghiuri.
Pentru problema triangulrii optime a unui poligon, se dau un poligon convex P =
hv0 , v1 , . . . , vn1 i i o funcie de ponderare w definit pe triunghiurile formate de laturile i
276 Capitolul 16 Programarea dinamic

Figura 16.4 Dou modaliti de triangulare ale unui poligon convex. Fiecare triangulare a acestui
poligon avnd 7 laturi are 7 3 = 4 coarde i mparte poligonul n 7 2 = 5 triunghiuri.

coardele lui P . Problema care se pune este gsirea unei triangulri care minimizeaz suma
ponderilor triunghiurilor din triangulare. O funcie de ponderare care pare natural este

w(4vi vj vk ) = |vi vj | + |vj vk | + |vk vi |,

unde |vi vj | reprezint distana euclidian de la vi la vj . Algoritmul pe care l vom descrie este
independent de alegerea funciei de ponderare.

Corespondena cu parantezarea
Exist o surprinztoare coresponden ntre triangularea unui poligon i parantezarea unei
expresii cum ar fi produsul unui ir de matrice. Aceast coresponden poate fi explicat cel mai
bine folosind arbori.
O parantezare complet a unei expresii corespunde unui arbore binar complet, uneori numit
i arbore de analiz gramatical a unei expresii. Figura 16.5(a) prezint un arbore de analiz
gramatical pentru parantezarea produsului irului de matrice

((A1 (A2 A3 ))(A4 (A5 A6 ))). (16.6)

Fiecare frunz a arborelui de analiz gramatical este etichetat cu unul dintre elementele
atomice din expresie (n cazul de fa matrice). Dac rdcina unui subarbore al arborelui de
analiz are un subarbore stng reprezentnd o expresie Es i un subarbore drept reprezentnd o
expresie Ed , atunci subarborele nsui reprezint expresia (Es Ed ). Aceasta este o coresponden
biunivoc ntre arborii de analiz gramatical i expresiile complet parantezate avnd n elemente
atomice.
O triangulare a unui poligon convex hv0 , v1 , . . . , vn1 i poate fi reprezentat, de asemenea,
printr-un arbore de analiz gramatical. Figura 16.5(b) prezint un astfel de arbore corespun-
ztor triangulrii poligonului din figura 16.4(a). Nodurile interne ale arborelui sunt coarde n
triangulare, iar latura v0 v6 este rdcina. Frunzele sunt celelalte laturi ale poligonului. Rdcina
v0 v6 este o latur a triunghiului 4v0 v3 v6 . Acest triunghi determin fiii rdcinii: unul este
16.4. Triangularea optim a poligoanelor 277

Figura 16.5 Arbori de analiz gramatical. (a) Arbore de analiz pentru parantezarea produsului
((A1 (A2 A3 ))(A4 (A5 A6 ))) i pentru triangularea poligonului avnd 7 laturi din figura 16.4(a). (b)
Triangularea poligonului, suprapus cu arborele de analiz. Fiecare matrice Ai corespunde laturii vi1 vi
pentru i = 1, 2, . . . , 6.

coarda v0 v3 , iar cellalt este coarda v3 v6 . S observm c acest triunghi mparte poligonul dat
n trei pri: triunghiul 4v0 v3 v6 nsui, poligonul hv0 , v1 , . . . , v3 i i poligonul hv3 , v4 , . . . , v6 i. Mai
mult, cele dou subpoligoane sunt formate, n ntregime, din laturi ale poligonului considerat,
cu excepia rdcinilor arborilor asociai lor, care sunt coardele v0 v3 i v3 v6 . ntr-o manier
recursiv, poligonul hv0 , v1 , . . . , v3 i conine subarborele stng al rdcinii arborelui de analiz,
iar poligonul hv3 , v4 , . . . , v6 i conine subarborele drept.
n general, o triangulare a unui poligon avnd n laturi corespunde unui arbore de analiz
avnd n 1 frunze. Printr-un mecanism invers, se poate realiza o triangulare plecnd de la un
arbore de analiz. Astfel exist o coresponden biunivoc ntre arborii de analiz i triangulri.
Cum un produs de n matrice complet parantezat corespunde unui arbore de analiz avnd n
frunze, el corespunde, de asemenea, unei triangulri a unui poligon avnd (n+1) vrfuri. Figurile
16.5(a) i (b) ilustreaz aceast coresponden. Fiecare matrice Ai dintr-un produs A1 A2 An
corespunde unei laturi vi1 vi a unui poligon avnd n + 1 vrfuri. O coard vi vj , unde i < j,
corespunde unei matrice Ai+1..j calculat n timpul evalurii produsului.
De fapt, problema nmulirii unui ir de matrice este un caz special al problemei triangulrii
optime. Aceasta nseamn c fiecare instan a produsului unui ir de matrice poate fi
transformat ntr-o problem de triangulare optim. Dndu-se un produs al unui ir de matrice
A1 A2 An , vom defini un poligon convex cu n + 1 vrfuri, P = hv0 , v1 , . . . , vn i. Dac matricea
Ai are dimensiunile pi1 pi pentru i = 1, 2, . . . , n, vom defini funcia de cost a triangulrii
astfel

w(4vi vj vk ) = pi pj pk .

O triangulare optim a lui P relativ la aceast funcie de cost produce un arbore de analiz
pentru o parantezare optim a produsului A1 A2 An .
Cu toate c reciproca nu este adevrat, adic problema triangulrii optime nu este un
278 Capitolul 16 Programarea dinamic

caz special al problemei nmulirii unui ir de matrice, se poate arta c procedura Ordine-
ir-Matrice din seciunea 16.1, cu anumite modificri minore, rezolv problema triangulrii
optime pentru un poligon avnd n + 1 vrfuri. Trebuie doar s nlocuim secvena hp0 , p1 , . . . , pn i
a dimensiunilor matricelor cu secvena hv0 , v1 . . . , vn i a vrfurilor, s schimbm toate referirile
la p n referiri la v i s schimbm linia 9 astfel:
9: q m[i, k] + m[k + 1, j] + w(4vi1 vk vj )
Dup execuia algoritmului, elementul m[1, n] conine ponderea unei triangulri optime. n
continuare vom justifica aceast afirmaie.

Substructura unei triangulri optime


S considerm o triangulare optim T a unui poligon avnd n + 1 vrfuri P = hv0 , v1 , . . . , vn i
care conine triunghiul 4v0 vk vn pentru un anumit k cu 1 k n 1. Ponderea asociat lui T
este suma ponderilor triunghiului 4v0 vk vn i a triunghiurilor corespunztoare triangulrii celor
dou subpoligoane hv0 , v1 , . . . , vk i i hvk , vk+1 , . . . , vn i. Triangularea subpoligoanelor determinate
de T trebuie, deci, s fie optim, deoarece, dac s-ar obine pentru unul dintre ele o pondere de
valoare mai mic, s-ar contrazice minimalitatea ponderii lui T .

O soluie recursiv
Aa cum, conform definiiei, m[i, j] este costul minim al calculului subprodusului irului de
matrice Ai Ai+1 Aj , fie t[i, j], pentru 1 i < j n, ponderea triangulrii optime a poligonului
hvi1 , vi , . . . , vj i. Prin convenie, vom considera poligonul degenerat hvi1 , vi i ca avnd pondere
0. Ponderea unei triangulri optime a poligonului P este dat de t[1, n].
Urmtorul pas este definirea recursiv a lui t[i, j]. Punctul de plecare este poligonul degenerat,
cel cu dou vrfuri: t[i, i] = 0 pentru i = 1, 2, . . . , n. Cnd j i 1, poligonul hvi1 , vi , . . . , vj i
are cel puin trei vrfuri. Dorim s minimizm suma dintre ponderea triunghiului 4vi1 vk vj i
ponderile triangulrilor optime pentru poligoanele hvi1 , vi . . . , vk i i hvk , vk+1 , . . . , vj i, relativ
la toate vrfurile vk , pentru k = i, i + 1, . . . , j 1. n concluzie, funcia recursiv este
(
0 dac i = j,
t[i, j] = min {t[i, k] + t[k + 1, j] + w(4vi1 vk vj )} dac i < j. (16.7)
ikj1

S comparm aceast recuren cu (16.2), recuren pe care am construit-o pentru numrul


m[i, j], reprezentnd numrul de nmuliri scalare necesare pentru a calcula Ai Ai+1 Aj .
Cu excepia funciei de ponderare, recurenele sunt identice, aadar, cu modificrile minore
menionate mai sus, procedura Ordine-ir-Matrice poate calcula ponderea unei triangulri
optime. La fel ca Ordine-ir-Matrice, procedura de triangulare optim se execut ntr-un
timp de ordinul (n3 ) i folosete un spaiu de memorie de ordinul (n2 ).

Exerciii
16.4-1 Demonstrai c orice triangulare a unui poligon convex avnd n vrfuri are n 3 coarde
i mparte poligonul n n 2 triunghiuri.
Probleme 279

Figura 16.6 apte puncte n plan poziionate pe o reea unitar. (a) Cel mai scurt circuit nchis,
de lungime 24,88 . . .. Acest circuit nu este bitonic. (b) Circuitul bitonic cel mai scurt pentru aceeai
mulime de puncte. Lungimea sa este 25,58 . . ..

16.4-2 Profesorul Guinevere sugereaz c un algoritm mai rapid pentru rezolvarea problemei
triangulrii optime poate exista n cazul particular n care ponderea triunghiului este chiar aria
sa. Este aceast afirmaie adevrat?
16.4-3 S presupunem c funcia de ponderare w este definit pe coardele triangulrii i nu pe
triunghiuri. Ponderea unei triangulri relative la w este suma ponderilor coardelor triangulrii.
Artai c problema triangulrii optime cu coarde ponderate este doar un caz particular al
problemei triangulrii optime cu triunghiuri ponderate.
16.4-4 Determinai o triangulare optim pentru un octogon regulat, avnd laturi egale cu
unitatea. Utilizai funcia de ponderare:
w(4vi vj vk ) = |vi vj | + |vj vk | + |vk vi |,
unde |vi vj | este distana euclidian de la vi la vj . (Un poligon regulat este un poligon cu laturi
i unghiuri interne egale.)

Probleme
16-1 Problema euclidian bitonic a comis-voiajorului
Problema euclidian a comis-voiajorului este problema determinrii celui mai scurt circuit
care leag o mulime dat de n puncte n plan. Figura 16.6(a) prezint soluia unei probleme n
care avem apte puncte. n cazul general, problema este NP-complet, deci determinarea soluiei
nu se poate face n timp polinomial (a se vedea capitolul 36).
J. L. Bentley a sugerat c problema poate fi simplificat prin restricionarea tipului de circuite
cutate, i anume la circuite bitonice, adic circuite care ncep din punctul cel mai din stnga,
merg numai de la stnga la dreapta ctre punctul cel mai din dreapta, iar apoi merg numai
ctre stnga, napoi spre punctul de plecare. Figura 16.6(b) prezint cel mai scurt circuit bitonic
pentru cele apte puncte. Determinarea unui astfel de circuit se poate face n timp polinomial.
Descriei un algoritm, avnd un timp de execuie O(n2 ), pentru determinarea unui circuit
bitonic optim. Se va presupune c dou puncte distincte nu au aceeai abscis. (Indicaie:
Parcugei de la stnga la dreapta, innd minte posibilitile optime pentru cele dou pri
ale circuitului.)
280 Capitolul 16 Programarea dinamic

16-2 Tiprire uniform


S considerm problema tipririi uniforme a unui paragraf cu ajutorul unei imprimante. Textul
de intrare este o succesiune de n cuvinte, de lungimi l1 , l2 , . . . , ln , lungimea fiind msurat n
caractere. Se dorete tiprirea uniform a paragrafului pe un anumit numr de linii, fiecare linie
avnd cel mult M caractere. Acest criteriu de uniformitate funcioneaz dup cum urmeaz:
dac o linie conine cuvintele de la cuvntul i la cuvntul j, cu i j iar ntre cuvintePjse las exact
un spaiu, numrul de spaii suplimentare de la sfritul unei linii este M j +i k=i lk , numr
care trebuie s fie nenegativ, astfel nct cuvintele s ncap pe linie. Dorim s minimizm suma
cuburilor numrului de spaii suplimentare de la sfritul liniilor, n raport cu toate liniile, mai
puin ultima. Elaborai un algoritm folosind metoda programrii dinamice, care s tipreasc
uniform la imprimant un paragraf de n cuvinte. Analizai timpul de execuie i spaiul de
memorie necesare algoritmului.

16-3 Distana de editare


Exist mai multe modaliti prin care un terminal inteligent actualizeaz o linie dintr-un
text, nlocuind un ir surs x[1..m] cu un ir destinaie y[1..n]: un singur caracter al irului
surs poate fi ters, nlocuit cu un alt caracter sau copiat n irul destinaie; sau dou caractere
adiacente ale irului surs pot fi interschimbate n timp ce sunt copiate n irul destinaie. Dup
ce au fost realizate toate operaiile, un ntreg sufix al irului surs poate fi ters, o astfel de
operaie fiind cunoscut sub numele de tergere pn la sfritul liniei (sau, mai pe scurt,
eliminare).
De exemplu, o modalitate de transformare a irului surs algoritm n irul destinaie
altruiti utilizeaz urmtoarea secven de operaii.

Operaie ir destinaie ir surs


copiaz a a lgoritm
copiaz l al goritm
nlocuiete g cu t alt oritm
terge o alt ritm
copiaz r altr itm
insereaz u altru itm
insereaz i altrui itm
insereaz altrui itm
schimb it n ti altruiti m
elimin m altruiti

Pentru a obine acelai rezultat operaiile pot fi executate n diverse ordini.


Fiecare dintre aceste operaii: tergerea, nlocuirea, copierea, inserarea, interschimbarea i
eliminarea, au asociate un cost. (Presupunem costul asociat nlocuirii unui caracter ca fiind mai
mic dect costurile combinate ale tergerii i inserrii; n caz contrar operaia de nlocuire nu
va fi utilizat). Costul unei secvene date de transformri este suma costurilor transformrilor
individuale. Pentru secvena de mai sus, costul transformrii cuvntului algoritm n altruiti
este

(3 cost(copiere))+cost(nlocuire)+cost(tergere)+(4 cost(inserare))+
cost(interschimbare)+cost(eliminare).
Probleme 281

Dndu-se dou secvene x[1..m] i y[1..n] i o mulime dat de costuri asociate operaiilor,
distana de editare de la x la y este costul celei mai puin costisitoare secvene de transformri
care l convertete pe x n y. Elaborai un algoritm, folosind metoda programrii dinamice, pentru
a determina distana de editare de la x[1..m] la y[1..n] i pentru a afia succesiunea optim de
transformri. Analizai timpul de execuie i spaiul de memorie necesare.

16-4 Planificarea unei recepii de ctre o companie


Profesorul McKenzie este consultantul preedintelui Corporaiei A.-B., care intenioneaz s
ofere o recepie pentru companiile ce o compun. Corporaia are o structur ierarhic, relaiile
de subordonare formeaz un arbore orientat, n care rdcina este preedintele. Fiecare angajat
are ataat un coeficient de convieuire, care este un numr real. Pentru a organiza o petrecere
plcut pentru toi participanii, preedintele dorete ca nici un angajat s nu se ntlneasc cu
eful su direct.

a. Descriei un algoritm pentru alctuirea listei invitailor. Scopul este de a maximiza suma
coeficienilor de convieuire a invitailor. Analizai timpul de execuie al algoritmului.

b. Cum poate profesorul s se asigure c preedintele va fi invitat la propria sa petrecere?

16-5 Algoritmul Viterbi


Programarea dinamic poate fi utilizat n cazul unui graf orientat G = (V, E) pentru recu-
noaterea vorbirii. Fiecare muchie (u, v) E este etichetat cu un sunet (u, v) dintr-o mulime
finit de sunete. Graful etichetat este un model formal al unei persoane care vorbete o limb
cu anumite restricii. Fiecare drum n graf care ncepe ntr-un vrf dat v0 V corespunde unei
secvene posibile de sunete produse de model. Eticheta unui drum este definit de concatenarea
etichetelor muchiilor care compun drumul respectiv.

a. Fie un graf G cu muchiile etichetate, un vrf v0 V i o secven s = h1 , 2 , . . . , k i


de caractere din . Descriei un algoritm eficient care returneaz un drum din G, dac
exist un astfel de drum, care ncepe din v0 i are eticheta s; n caz contrar, algoritmul va
returna nu-exist-drum. Analizai timpul de execuie al algoritmului. (Indicaie: pot fi
utile noiunile din capitolul 23.)

S presupunem acum c fiecare muchie (u, v) E are asociat, de asemenea, o probabilitate


nenegativ p(u, v) de traversare a muchiei (u, v) dinspre vrful u i de producere a sunetului
corespunztor. Suma probabilitilor asociate muchiilor care pleac din orice vrf este 1. Pro-
babilitatea asociat unui drum se definete ca fiind produsul probabilitilor asociate muchiilor
care l compun. Putem interpreta probabilitatea asociat unui drum care pleac din v0 , ca fiind
probabilitatea ca un traseu aleator care ncepe n v0 s urmeze drumul specificat; selectarea
muchiei care pleac dintr-un vrf u se face probabilistic, conform probabilitilor muchiilor care
pleac din u.

b. Extindei rspunsurile de la punctul (a) astfel nct, dac este returnat un drum, acesta
este cel mai probabil drum plecnd din v0 i avnd eticheta s. Analizai timpul de execuie
al algoritmului.
282 Capitolul 16 Programarea dinamic

Note bibliografice
R. Bellman a nceput studiul sistematic al metodei programrii dinamice n 1955. Cuvntul
programare, ca i n programarea liniar, face referire la utilizarea unei metode care furnizeaz
soluii n mod tabelar. Cu toate c tehnicile de optimizare care incorporeaz elemente de
programare dinamic erau cunoscute anterior, Bellman a mbogit domeniul cu o baz
matematic solid [21].
Hu i Shing [106] au propus un algoritm avnd timp de execuie O(n lg n) pentru problema
nmulirii irului de matrice. Ei au demonstrat, de asemenea, corespondena ntre problema
triangulrii optime a poligoanelor i problema nmulirii unui ir de matrice.
Algoritmul avnd timp de execuie O(mn) pentru determinarea celui mai lung subir comun
pare a avea mai muli autori. Knuth [43] a pus ntrebarea dac exist algoritmi avnd timp de
execuie mai redus dect timp ptratic pentru problema CMLSC. Masek i Paterson [143] au
rspuns afirmativ acestei ntrebri propunnd un algoritm cu timp de execuie O(mn/ lg n) unde
n m, iar secvenele sunt extrase dintr-o mulime mrginit. Pentru cazul particular n care
nici un element nu apare mai mult dect o dat ntr-o secven de intrare, Szymanski [184] a
artat c problema poate fi rezolvat ntr-un timp de ordinul O((n+m) lg (n + m)). Multe dintre
aceste rezultate se extind la problema calculrii distanelor de editare (problema 16-3).
17 Algoritmi greedy

Algoritmii aplicai problemelor de optimizare sunt, n general, compui dintr-o secven de


pai, la fiecare pas existnd mai multe alegeri posibile. Pentru multe probleme de optimizare,
utilizarea metodei programrii dinamice pentru determinarea celei mai bune soluii se dovedete
a fi o metod prea complicat. Un algoritm greedy va alege la fiecare moment de timp soluia
ce pare a fi cea mai bun la momentul respectiv. Deci este vorba despre o alegere optim, fcut
local, cu sperana c ea va conduce la un optim global. Acest capitol trateaz probleme de
optimizare ce pot fi rezolvate cu ajutorul algoritmilor greedy.
Algoritmii greedy conduc n multe cazuri la soluii optime, dar nu ntotdeauna. . . n seciunea
17.1 vom prezenta mai nti o problem simpl dar netrivial, problema selectrii activitilor, a
crei soluie poate fi calculat n mod eficient cu ajutorul unei metode de tip greedy. n seciunea
17.2 se recapituleaz cteva elemente de baz ale metodei greedy. n seciunea 17.3 este descris
o aplicaie important a metodei greedy: proiectarea unor coduri pentru compactarea datelor
i anume codurile Huffman. n seciunea 17.4 sunt investigate structuri combinatoriale numite
matroizi pentru care algoritmii greedy produc ntotdeauna soluie optim. n ncheiere, n
seciunea 17.5 se exemplific utilizarea matroizilor pentru problema planificrii sarcinilor de
timp unitar, sarcini avnd anumii termeni limit de realizare i anumite penalizri n caz de
nendeplinire.
Metoda greedy este destul de puternic i se aplic cu succes unui spectru larg de probleme.
Capitolele urmtoare vor prezenta mai muli algoritmi ce pot fi privii ca aplicaii ale metodei
greedy, cum ar fi algoritmii de determinare a arborelui parial de cost minim (capitolul 24),
algoritmul lui Dijkstra pentru determinarea celor mai scurte drumuri pornind dintr-un vrf
(capitolul 25) i algoritmul lui Chvatal, o euristic pentru determinarea acoperirii unei mulimi
(capitolul 37). Arborii pariali de cost minim sunt un exemplu clasic pentru metoda greedy.
Cu toate c acest capitol i capitolul 24 pot fi studiate independent, cititorul poate gsi util
parcurgerea lor paralel.

17.1. O problem de selectare a activitilor


Primul exemplu pe care l vom considera este o problem de repartizare a unei resurse mai
multor activiti care concureaz pentru a obine resursa respectiv. Vom vedea c un algoritm
de tip greedy reprezint o metod simpl i elegant pentru selectarea unei mulimi maximale
de activiti mutual compatibile.
S presupunem c dispunem de o mulime S = 1, 2, . . . , n de n activiti care doresc s
foloseasc o aceeai resurs (de exemplu o sal de lectur). Aceast resurs poate fi folosit de o
singur activitate la un anumit moment de timp. Fiecare activitate i are un timp de pornire
si i un timp de oprire fi , unde si fi . Dac este selecionat activitatea i, ea se desfoar
pe durata intervalului [si , fi ). Spunem c activitile i i j sunt compatibile dac intervalele
[si , fi ) i [sj , fj ) nu se intersecteaz (adic i i j sunt compatibile dac si fj sau sj fi ).
Problema selectrii activitilor const din selectarea unei mulimi maximale de activiti
mutual compatibile.
284 Capitolul 17 Algoritmi greedy

Un algoritm greedy pentru aceast problem este descris de urmtoarea procedur, prezentat
n pseudocod. Vom presupune c activitile (adic datele de intrare) sunt ordonate cresctor
dup timpul de terminare:
f1 f2 . . . fn . (17.1)
n caz contrar aceast ordonare poate fi fcut n timp O(n lg n). Algoritmul de mai jos presupune
c datele de intrare s i f sunt reprezentate ca vectori.
Selector-Activiti-Greedy(s, f )
1: n lungime[s]
2: A {1}
3: j 1
4: pentru i 2, n execut
5: dac si fj atunci
6: A A {i}
7: ji
8: returneaz A

Operaiile realizate de algoritm pot fi vizualizate n figura 17.1. n mulimea A se introduc


activitile selectate. Variabila j identific ultima activitate introdus n A. Deoarece activitile
sunt considerate n ordinea nedescresctoare a timpilor lor de terminare, fj va reprezenta
ntotdeauna timpul maxim de terminare a oricrei activiti din A. Aceasta nseamn c
fj = max{fk : k A} (17.2)
n liniile 23 din algoritm se selecteaz activitatea 1, se iniializeaz A astfel nct s nu conin
dect aceast activitate, iar variabila j ia ca valoare aceast activitate. n continuare liniile 47
consider pe rnd fiecare activitate i i o adaug mulimii A dac este compatibil cu toate
celelalte activiti deja selectate. Pentru a vedea dac activitatea i este compatibil cu toate
celelalte activiti existente la momentul curent n A, este suficient, conform ecuaiei (17.2), s
fie ndeplinit condiia din linia 5 adic momentul de pornire si s nu fie mai devreme dect
momentul de oprire fj al activitii cel mai recent adugate mulimii A. Dac activitatea i este
compatibil, atunci n liniile 67 ea este adugat mulimii A, iar variabila j este actualizat.
Procedura Selector-Activiti-Greedy este foarte eficient. Ea poate planifica o mulime
S de n activiti n (n), presupunnd c activitile au fost deja ordonate dup timpul lor de
terminare. Activitatea aleas de procedura Selector-Activiti-Greedy este ntotdeauna
cea cu primul timp de terminare care poate fi planificat legal. Activitatea astfel selectat
este o alegere greedy (lacom) n sensul c, intuitiv, ea las posibilitatea celorlalte activiti
rmase pentru a fi planificate. Cu alte cuvinte, alegerea greedy maximizeaz cantitatea de timp
neplanificat rmas.

Demonstrarea corectitudinii algoritmului greedy


Algoritmii de tip greedy nu furnizeaz ntotdeauna soluiile optime. Cu toate acestea,
algoritmul Selector-Activiti-Greedy determin ntotdeauna o soluie optim pentru o
instan a problemei selectrii activitilor.
Teorema 17.1 Algoritmul Selector-Activiti-Greedy furnizeaz soluii de dimensiune
maxim pentru problema selectrii activitilor.
17.1. O problem de selectare a activitilor 285

Figura 17.1 Operaiile algoritmului Selector-Activiti-Greedy asupra celor 11 activiti date


n stnga. Fiecare linie a figurii corespunde unei iteraii din ciclul pentru din liniile 47. Activitile
care au fost selectate pentru a fi incluse n mulimea A sunt haurate, iar activitatea curent i este
nehaurat. Dac timpul de pornire si al activitii i este mai mic dect timpul de terminare al activitii
j (sgeata dintre ele este spre stnga), activitatea este ignorat. n caz contrar (sgeata este ndreptat
spre dreapta), activitatea este acceptat i este adugat mulimii A.

Demonstraie. Fie S = {1, 2, . . . , n} mulimea activitilor care trebuie planificate. Deoarece


presupunem c activitile sunt ordonate dup timpul de terminare, activitatea 1 se va termina
286 Capitolul 17 Algoritmi greedy

cel mai devreme. Vrem s artm c exist o soluie optim care ncepe cu activitatea 1, conform
unei alegeri greedy.
S presupunem c A S este o soluie optim pentru o instan dat a problemei selectrii
activitilor. Vom ordona activitile din A dup timpul de terminare. Mai presupunem c prima
activitate din A este activitatea k. Dac k = 1, planificarea mulimii A ncepe cu o alegere greedy.
Dac k 6= 1 vrem s artm c exist o alt soluie optim B a lui S care ncepe conform alegerii
greedy, cu activitatea 1. Fie B = A {k} {1}. Deoarece f1 fk , activitile din B sunt
distincte, i cum B are acelai numr de activiti ca i A, B este de asemenea optim. Deci B
este o soluie optim pentru S, care conine alegerea greedy a activitii 1. Am artat astfel c
exist ntotdeauna o planificare optim care ncepe cu o alegere greedy.
Mai mult, o dat ce este fcut alegerea greedy a activitii 1, problema se reduce la
determinarea soluiei optime pentru problema selectrii acelor activiti din S care sunt
compatibile cu activitatea 1. Aceasta nseamn c dac A este o soluie optim pentru problema
iniial, atunci A0 = A {1} este o soluie optim pentru problema selectrii activitilor
S 0 = {i S : si f1 }. De ce? Dac am putea gsi o soluie B 0 pentru S 0 cu mai multe
activiti dect A0 , adugarea activitii 1 la B 0 va conduce la o soluie B a lui S cu mai multe
activiti dect A, contrazicndu-se astfel optimalitatea mulimii A. n acest mod, dup ce este
fcut fiecare alegere greedy, ceea ce rmne este o problem de optimizare de aceeai form ca
problema iniial. Prin inducie dup numrul de alegeri fcute, se arat c realiznd o alegere
greedy la fiecare pas, se obine o soluie optim.

Exerciii
17.1-1 Elaborai un algoritm conform metodei programrii dinamice pentru problema selectrii
activitilor, bazat pe calcularea valorilor mi , iterativ pentru i = 1, 2, . . . , n, unde mi este
dimensiunea celei mai mari mulimi de activiti compatibile dintre activitile {1, 2, . . . , i}.
Se va presupune c datele de intrare au fost ordonate conform ecuaiei (17.1). Comparai timpul
de execuie al algoritmului gsit cu cel al procedurii Selector-Activiti-Greedy.

17.1-2 S presupunem c avem o mulime de activiti de planificat pentru un numr mare de


sli de lectur. Se dorete planificarea tuturor activitilor folosindu-se ct mai puine sli de
lectur posibil. Elaborai un algoritm greedy eficient pentru a determina ce activitate trebuie s
utilizeze o sal de lectur i care anume.
(Aceast problem este cunoscut de asemenea sub numele de problema colorrii gra-
furilor interval . Putem crea un graf interval ale crui vrfuri sunt activitile date i ale
crui muchii conecteaz activitile incompatibile. Determinarea celui mai mic numr de culori
necesare pentru a colora fiecare vrf, astfel nct dou vrfuri adiacente s nu aib aceeai cu-
loare, este echivalent cu determinarea numrului minim de sli de lectur necesare planificrii
tuturor activitilor date.)

17.1-3 Nu orice algoritm de tip greedy aplicat problemei selctrii activitilor produce o mulime
maximal de activiti compatibile. Dai un exemplu care s arate c tehnica selectrii activitii
cu timpul de executare cel mai scurt dintre activitile compatibile cu cele deja selectate, nu este
corect. Se cere acelai lucru pentru ncercarea de a selecta ntotdeauna activitatea care se
suprapune cu cele mai puine dintre activitile rmase.
17.2. Elemente ale strategiei greedy 287

17.2. Elemente ale strategiei greedy


Un algoritm greedy determin o soluie optim a unei probleme n urma unei succesiuni de
alegeri. La fiecare moment de decizie din algoritm este aleas opiunea care pare a fi cea mai
potrivit. Aceast strategie euristic nu produce ntotdeauna soluia optim, dar exist i cazuri
cnd aceasta este obinut, ca n cazul problemei selectrii activitilor. n acest paragraf vom
prezenta cteva proprieti generale ale metodei greedy.
Cum se poate decide dac un algoritm greedy poate rezolva o problem particular de opti-
mizare? n general nu exist o modalitate de a stabili acest lucru, dar exist dou caracteristici
pe care le au majoritatea problemelor care se rezolv prin tehnici greedy: proprietatea de alegere
greedy i substructura optim.

Proprietatea de alegere greedy


Prima caracteristic a unei probleme este aceea de a avea proprietatea alegerii greedy ,
adic se poate ajunge la o soluie optim global, realiznd alegeri (greedy) optime local. Aici
intervine diferena dintre algoritmii greedy i programarea dinamic. La rezolvarea unei metode
prin metoda programrii dinamice la fiecare pas al algoritmului se face cte o alegere dar ea
depinde de soluiile subproblemelor. ntr-un algoritm greedy se realizeaz orice alegere care pare
a fi cea mai bun la momentul respectiv, iar subproblema rezultat este rezolvat dup ce alegerea
este fcut. Alegerea realizat de un algoritm greedy poate depinde de alegerile fcute pn n
momentul respectiv, dar nu poate depinde de alegerile ulterioare sau de soluiile subproblemelor.
Astfel, spre deosebire de programarea dinamic prin care se rezolv subproblemele n manier
bottom-up, o strategie greedy de obicei progreseaz n manier top-down, realiznd alegeri
greedy succesive i reducnd iterativ dimensiunea problemei respective.
Desigur, trebuie s demonstrm c o alegere greedy la fiecare pas conduce la o soluie optim
global, i aceasta este o problem mai delicat. De obicei, ca n cazul teoremei 17.1, demonstraia
examineaz o soluie optim global. Apoi se arat c soluia poate fi modificat astfel nct la
fiecare pas este realizat o alegere greedy, iar aceast alegere reduce problema la una similar
dar de dimensiuni mai reduse. Se aplic apoi principiul induciei matematice pentru a arta c o
alegere greedy poate fi utilizat la fiecare pas. Faptul c o alegere greedy conduce la o problem
de dimensiuni mai mici reduce demonstaia corectitudinii la demonstrarea faptului c o soluie
optim trebuie s evidenieze o substructur optim.

Substructur optim
O problem evideniaz o substrucutr optim dac o soluie optim a problemei conine
soluii optime ale subproblemelor. Aceast proprietate este cheia pentru aplicarea programrii
dinamice sau a unui algoritm greedy. Ca exemplu al unei structuri optime, s ne reamintim
demonstraia teoremei 17.1, unde se arat c dac o soluie optim A a problemei selectrii
activitilor ncepe cu activitatea 1, atunci mulimea activitilor A0 = A {1} este o soluie
optim pentru problema selectrii activitilor S 0 = {i S : si f1 }.
288 Capitolul 17 Algoritmi greedy

Comparaie ntre metoda Geedy i metoda programrii dinamice


Deoarece proprietatea de substructur optim este exploatat att de metoda greedy ct i de
cea a programrii dinamice, poate exista tentaia de a genera o soluie prin metoda programrii
dinamice, cu toate c un algoritm greedy ar fi suficient, sau invers, se poate crede c un algoritm
greedy poate produce o soluie optim n timp ce corect ar trebui aplicat metoda programrii
dinamice. Pentru a ilustra diferenele dintre cele dou metode vom analiza n continuare dou
variante ale unei probleme clasice de optimizare.
Problema 01 a rucsacului se formuleaz dup cum urmeaz. Un ho care jefuiete un
magazin gsete n obiecte; obiectul i are valoarea vi i greutatea wi , unde vi i wi sunt numere
ntregi. El dorete s ia o ncrctur ct mai valoroas posibil, dar nu poate cra n sac o
greutate total mai mare dect W , unde W este i el un numr ntreg. Ce obiecte trebuie s ia?
(Aceast problem poart numele de problema 0-1 a rucsacului pentru c un obiect fie este luat
n ntregime fie deloc; houl nu poate lua o parte din obiect sau un acelai obiect de mai multe
ori).
n problema fracionar a rucsacului hoului i este permis s ia i pri din obiecte.
Un obiect din problema 0-1 a rucsacului poate fi gndit ca un lingou de aur, iar un obiect din
problema fracionar a rucsacului poate fi imaginat ca o anumit cantitate de praf de aur.
La ambele probleme se evideniaz proprietatea de substructur optim. Pentru problema
01, considerm ncrctura cea mai valoroas cea avnd greutatea cel mult W . Dac din
ncrctur se scoate obiectul j, ceea ce rmne trebuie s fie o ncrctur avnd greutatea
cel mult W wj pe care houl o poate lua dintre cele n 1 obiecte iniiale, mai puin j.
Pentru problema fracionar vom considera c dac ndeprtm un obiect j de greutate w din
ncrctura optim, ceea ce rmne trebuie s fie cea mai valoroas ncrctur avnd greutatea
cel mult W w pe care houl o poate lua dintre cele n 1 obiecte iniiale, plus greutatea wj w
din obiectul j.
Cu toate c problemele sunt similare, problema fracionar a rucsacului poate fi rezolvat
printr-un algoritm de tip greedy, n timp ce pentru pentru problema 01 nu este corect o astfel de
rezolvare. Pentru a rezolva problema fracionar calculm mai nti valoarea vi /wi (valoare per
greutate) pentru fiecare obiect. Respectnd o strategie greedy, houl ncepe prin a lua ct poate
de mult din obiectul avnd valoarea per greutate maxim. n cazul n care obiectul respectiv a
fost epuizat iar houl mai poate cra, el va lua ct de mult posibil din obiectul cu urmtoarea
valoare per greutate, n ordine descresctoare i aa mai departe, pn nu mai poate ncrca n
rucsac. Astfel, prin ordonarea valorilor per greutate, algoritmul greedy se execut n O(n lg n)
uniti de timp. Lsm ca exerciiu demonstrarea faptului c problema fracionar a rucsacului
are proprietatea alegerii greedy.
Pentru a arta c pentru problema 01 a rucsacului nu se poate folosi o strategie greedy, vom
considera instana problemei ilustat n figura 17.2(a). n aceast figur exist trei obiecte, iar
rucsacul are capacitatea 50 de uniti. Primul obiect cntrete 10 i valoreaz 60. Obiectul al
doilea are greutatea 20 i valoarea 100, iar al treilea cntrete 30 i are o valoarea 120. Astfel,
valoarea/greutate a primului obiect este 6 care este mai mare dect valoarea/greutate a celui
de-al doilea obiect (2) sau a celui de-al treilea obiect (4). Conform strategiei greedy, la nceput
va fi selectat obiectul 1. Cu toate acestea, dup cum se poate vedea din analiza din figura 17.2(b)
soluia optim alege obiectele 2 i 3 i las obiectul 1 deoparte. Nici una din cele dou soluii
posibile care conin obiectul 1 nu sunt optime.
Pentru problema fracionar similar, strategia greedy consider mai nti obiectul 1 i
17.2. Elemente ale strategiei greedy 289

Figura 17.2 Strategia greedy nu funcioneaz pentru problema 01 a rucsacului. (a) Houl trebuie
s selecteze o submulime a celor trei obiecte din figur a cror greutate nu trebuie s depeasc 50
de uniti. (b) Submulimea optim cuprinde elementele 2 i 3. Orice soluie care conine obiectul 1
nu este optim, chiar dac obiectul 1 are valoarea cea mai mare a ctului valoare/greutate. (c) Pentru
problema fracionar a rucsacului strategia considerrii obiectelor n ordinea celei mai mari valori a
ctului valoare/greutate conduce la soluia optim.

conduce la o soluie optim aa cum se vede n figura 17.2(c).


Considerarea obiectului 1 nu este valabil n problema rucsacului 01 deoarece houl nu
poate s umple rucsacul pn la capacitatea lui maxim, iar spaiul liber micoreaz ctul
valoare/greutate a ncrcturii sale. n problema 01, atunci cnd lum n considerare un obiect
pentru a-l pune n rucsac, trebuie s comparm soluia subproblemei n care obiectul este inclus
cu soluia subproblemei n care obiectul lipsete. Comparaia trebuie realizat nainte de a face
alegerea. Problema formulat n acest mod produce o serie de subprobleme care se suprapun o
caracteristic a programrii dinamice, care poate fi ntr-adevr folosit (vezi exerciiul 17.2-2).

Exerciii
17.2-1 Artai c problema rucsacului fracionar are propietatea alegerii greedy.

17.2-2 Rezolvai prin metoda programrii dinamice problema 0-1 a rucsacului. Soluia trebuie
s fie calculat n O(nW ) uniti de timp, unde n este numrul de obiecte, iar W este greutatea
maxim a obiectelor pe care houl le poate ncrca n rucsac.

17.2-3 S presupunem c n problema 01 a rucsacului, ordinea obiectelor dup sortarea


cresctoare dup greutate este aceeai ca i dup sortarea descresctoare dup valoare. Elaborai
un algoritm eficient pentru a determina o soluie optim a acestei variante a problemei rucsacului
i argumentai corectitudinea algoritmului.

17.2-4 Profesorul Midas conduce un automobil de la Newark la Reno pe autostrada 80. Maina
sa are un rezervor de benzin care, dac este plin, asigur cltoria pentru n kilometri. Harta
pe care profesorul o are indic distana n kilometri ntre staiile de benzin de pe drum. El
dorete s se opreasc de ct mai puine ori. Descriei o metod eficient prin care profesorul
Midas poate s determine staiile de benzin la care trebuie s se opreasc i artai c strategia
respectiv conduce la o soluie optim.
290 Capitolul 17 Algoritmi greedy

a b c d e f
Frecven (n mii) 45 13 12 16 9 5
Cuvnt codificat; lungime fix 000 001 010 011 100 101
Cuvnt codificat; lungime variabil 0 101 100 111 1101 1100

Figura 17.3 O problem de codificare a caracterelor. Un fiier de 100.000 de caractere conine doar
caracterele a-f, cu frecvenele indicate. Dac fiecrui caracter i este asociat un cuvnt de cod pe 3 bii,
fiierul codificat va avea 300.000 de bii. Folosind codificarea cu lungime variabil, fiierul codificat va
ocupa doar 224.000 de bii.

17.2-5 Fie dat o mulime {x1 , x2 , . . . , xn } de puncte de pe dreapta real. Descriei un algoritm
eficient care determin cea mai mic mulime de intervale nchise de lungime egal cu unitatea,
care conin toate punctele date. Argumentai corectitudinea algoritmului.

17.2-6 ? Artai cum se poate rezolva problema fracionar a rucsacului n O(n) uniti de
timp. Presupunei c avei deja o soluie pentru problema 10-2.

17.3. Coduri Huffman


Codurile Huffman reprezint o tehnic foarte utilizat i eficient pentru compactarea datelor;
n funcie de caracteristicile fiierului care trebuie comprimat, spaiul economisit este ntre 20%
i 90%. Algoritmul greedy pentru realizarea acestei codificri utilizeaz un tabel cu frecvenele
de apariie ale fiecrui caracter. Ideea este de a utiliza o modalitate optim pentru reprezentarea
fiecrui caracter sub forma unui ir binar.
S presupunem c avem un fiier ce conine 100.000 de caractere, pe care dorim s l memorm
ntr-o form compactat. Frecvenele de apariie ale caracterelor n text sunt date de figura 17.3:
exist doar ase caractere diferite i fiecare dintre ele apare de 45.000 de ori.
Exist mai multe modaliti de reprezentare a unui astfel de fiier. Vom considera problema
proiectrii unui cod binar al caracterelor (pe scurt cod ) astfel nct fiecare caracter este
reprezentat printr-un ir binar unic. Dac utilizm un cod de lungime fix, avem nevoie de
3 bii pentru a reprezenta ase caractere: a=000, b=001, . . . , f=101. Aceast metod necesit
300.000 de bii pentru a codifica tot fiierul. Se pune problema dac se poate face o compactare
i mai bun.
O codificare cu lungime variabil poate mbunti semnificativ performanele, atribuind
caracterelor cu frecvene mai mari cuvinte de cod mai scurte iar celor cu frecvene mai reduse
cuvinte de cod mai lungi. Figura 17.3 prezint o astfel de codificare; irul 0 avnd lungimea de
1 bit reprezint caracterul a n timp ce irul 1100 de lungime 4 reprezint caracterul f. Aceast
codificare necesit (45 1 + 13 3 + 12 3 + 16 3 + 9 4 + 5 4) 1.000 = 224.000 bii pentru a
reprezenta un fiier i economisete aproximativ 25% din spaiu. Vom vedea c aceasta este de
fapt o codificare-caracter optim pentru acest fiier.
17.3. Coduri Huffman 291

Figura 17.4 Arborii corespunztori schemelor de codificare din figura 17.3. Fiecare frunz este
etichetat cu un caracter i cu frecvena de apariie a acestuia. Fiecare nod intern este etichetat cu
suma ponderilor frunzelor din subarborele aferent. (a) Arborele corespunztor codificrii de lungime
fix a=000, . . ., f=101 (b) Arborele asociat codificrii prefix optime a=0, b=101,. . ., f=1100.

Coduri prefix
Vom considera n continuare doar codificrile n care nici un cuvnt de cod nu este prefixul
altui cuvnt. Astfel de codificri se numesc codificri prefix 1 . Se poate arta (cu toate c nu
vom proceda astfel n cazul de fa) c o compresie optim a datelor, realizat prin codificarea
caracterelor, poate fi realizat i prin codificarea prefix, deci considerarea codificrii prefix nu
scade din generalitate.
Codificarea prefix este util deoarece simplific att codificarea (deci compactarea) ct i
decodificarea. Codificarea este ntotdauna simpl pentru orice codificare binar a caracterelor;
se concatenenaz cuvintele de cod reprezentnd fiecare caracter al fiierului. De exemplu, prin
codificarea prefix avnd lungime variabil din figura 17.3, putem codifica un fiier de 3 caractere
abc astfel: 0101100=0101100, unde semnul reprezint operaia de concatenare.
Decodificarea este de asemenea relativ simpl pentru codurile prefix. Cum nici un cuvnt de
cod nu este prefixul altuia, nceputul oricrui fiier codificat nu este ambiguu. Putem deci s
identificm cuvntul iniial de cod, s l traducem n caracterul original, s-l ndeprtm din
fiierul codificat i s repetm procesul pentru fiierul codificat rmas. n exemplul nostru, irul
001011101 se translateaz automat n 001011101, secven care se decodific n aabe.
Procesul de decodificare necesit o reprezentare convenabil a codificrii prefix astfel nct
cuvntul iniial de cod s poat fi uor identificat. O astfel de reprezentare poate fi dat de un
arbore binar ale crui frunze sunt caracterele date. Interpretm un cuvnt de cod binar pentru
un caracter ca fiind drumul de la rdcin pn la caracterul respectiv, unde 0 reprezint mergi
la fiul stng iar 1 mergi la fiul drept. n figura 17.4 sunt prezentai arborii pentru cele dou
codificri ale exemplului nostru. Observai c acetia nu sunt arbori binari de cutare, deoarece
frunzele nu trebuie s fie ordonate, iar nodurile interne nu conin chei pentru caractere.
O codificare optim pentru un fiier este ntotdeuna reprezentat printr-un arbore binar
complet, n care fiecare vrf care nu este frunz are doi fii (vezi exerciiul 17.3-1).
Codificarea cu lungime fix din exemplul de mai sus nu este optim deoarece arborele asociat,
1 Codificare independent de prefix este probabil o denumire mai potrivit, dar termenul de codificare prefix

este cel cunoscut n literatura de specialitate.


292 Capitolul 17 Algoritmi greedy

prezentat n figura 17.4(a), nu este un arbore binar complet: exist dou cuvinte de cod care ncep
cu 10. . ., dar nici unul care s nceap cu 11. . .. Conform celor de mai sus ne putem restrnge
atenia numai asupra arborilor binari complei, deci dac C este alfabetul din care fac parte
caracterele, atunci arborele pentru o codificare prefix optim are exact |C| frunze, una pentru
fiecare liter din alfabet, i exact |C| 1 noduri interne.
Dndu-se un arbore T , corespunztor unei codificri prefix, este foarte simplu s calculm
numrul de bii necesari pentru a codifica un fiier. Pentru fiecare caracter c din alfabet, fie
f (c) frecvena lui c n fiier i s notm cu dT (c) adncimea frunzei n arbore (adic nivelul pe
care se afl). S observm c dT (c) reprezint de asemenea cuvntul de cod pentru caracterul c.
Numrul de bii necesari pentru a codifica un fiier este
X
B(T ) = f (c)dT (c), (17.3)
cC

Vom numi acest numr costul arborelui T .

Construcia unui cod Huffman


Huffman a inventat un algoritm greedy care construiete o codificare prefix optim numit
codul Huffman. Algoritmul construiete arborele corespunztor codificrii optime, ntr-o
manier bottom-up. Se ncepe cu o mulime de | C | frunze i se realizeaz o secven de
| C | 1 operaii de fuzionri pentru a crea arborele final.
n algoritmul n pseudocod care urmeaz, vom presupune c C este o mulime de n caractere i
fiecare caracter c C este un obiect avnd o frecven dat f [c]. Va fi folosit o coad de prioriti
pentru a identifica cele dou obiecte cu frecvena cea mai redus care vor fuziona. Rezultatul
fuzionrii celor dou obiecte este un nou obiect a crui frecven este suma frecvenelor celor
dou obiecte care au fuzionat.
Huffman(C)
1: n |C|
2: Q C
3: pentru i 1, n 1 execut
4: z Aloc-Nod()
5: x stnga[z] Extrage-Min(Q)
6: y dreapta[z] Extrage-Min(Q)
7: f [z] f [x] + f [y]
8: Insereaz(Q, z)
9: returneaz Extrage-Min(Q)

Pentru exemplul nostru, algoritmul lui Huffman lucreaz ca n figura 17.5. Deoarece exist
6 litere n alfabet, dimensiunea iniial a cozii este n = 6, iar pentru a construi arborele sunt
necesari 5 pai de fuzionare. Arborele final reprezint codificarea prefix optim. Codificarea unei
litere este secvena etichetelor nodurilor ce formeaz drumul de la rdcin la liter.
n linia 2, coada de prioriti Q este iniializat cu caracterele din C. Ciclul pentru din
liniile 38 extrage n mod repetat dou noduri x i y cu cea mai mic frecven din coad, i le
nlocuiete n coad cu un nou nod z, reprezentnd fuziunea lor. Frecvena lui z este calculat
n linia 7 ca fiind suma frecvenelor lui x i y. Nodul z are pe x ca fiu stng i pe y ca fiu drept.
(Aceast ordine este arbitrar; interschimbarea fiilor stng i drept ai oricrui nod conduce la
17.3. Coduri Huffman 293

o codificare diferit, dar de acelai cost.) Dup n 1 fuzionri, unicul nod rmas n coad
rdcina arborelui de codificare este returnat n linia 9.
Analiza timpului de execuie pentru algoritmul lui Huffman presupune implementarea lui Q
sub forma unui heap binar (vezi capitolul 7). Pentru o mulime C de n caractere, iniializarea
lui Q n linia 2 poate fi realizat n O(n) uniti de timp utiliznd procedura Construiete-
Heap din seciunea 7.3. Ciclul pentru din liniile 38 se execut de exact | n | 1 ori, i cum
fiecare operaie asupra stivei necesit un timp O(n lg n), ciclul contribuie cu O(n lg n) la timpul
de execuie. Deci timpul total de execuie a procedurii Huffman pe o mulime de n caractere
este O(n lg n).

Corectitudinea algoritmului lui Huffman


Pentru a demonstra c algoritmul de tip greedy al lui Huffman este corect, vom arta c
problema determinrii unei codificri prefix optime implic alegeri greedy i are o substructur
optim. Urmtoarea lem se refer la proprietatea alegerii greedy.
Lema 17.2 Fie C un alfabet n care fiecare caracter c C are frecvena f [c]. Fie x i y dou
caractere din C avnd cele mai mici frecvene. Atunci exist o codificare prefix optim pentru
C n care cuvintele de cod pentru x i y au aceeai lungime i difer doar pe ultimul bit.
Demonstraie. Ideea demonstraiei este de a lua arborele T reprezentnd o codificare prefix
optim i a-l modifica pentru a realiza un arbore reprezentnd o alt codificare prefix optim. n
noul arbore, caracterele x i y vor apare ca frunze cu acelai tat i se vor afla pe nivelul maxim
n arbore. Dac putem realiza acest lucru, atunci cuvintele lor de cod vor avea aceeai lungime
i vor diferi doar pe ultimul bit.
Fie b i c dou caractere reprezentnd noduri terminale (frunze) frai situate pe nivelul maxim
al arborelui T . Fr a restrnge generalitatea, vom presupune c f [b] f [c] i f [x] f [y]. Cum
f [x] i f [y] sunt frunzele cu frecvenele cele mai sczute, n aceast ordine, iar f [b] i f [c] sunt
deci frecvene arbitrare, n ordine, avem f [x] f [b] i f [y] f [c]. Dup cum se vede n figura
17.6, vom schimba n T poziiile lui b i x pentru a produce arborele T 0 , iar apoi vom schimba n
T 0 poziiile lui c i y pentru a obine arborele T 00 . Conform ecuaiei (17.3), diferena costurilor
lui T i T 0 este
X X
B(T ) B(T 0 ) = f (c)dT (c) f (c)dT 0 (c)
cC cC
= f [x]dT (x) + f [b]dT (b) f [x]dT 0 (x) f [b]dT 0 (b)
= f [x]dT (x) + f [b]dT (b) f [x]dT 0 (b) f [b]dT 0 (x)
= (f [b] f [x])(dT (b) dT (x)) 0,
deoarece att f [b] f [x] i dT [b] dT [x] sunt nenegative. Mai precis, f [b] f [x] este nenegativ
deoarce x este frunza avnd frecvena minim iar dT [b] dT [x] este nenegativ pentru c b este
o frunz aflat pe nivelul maxim n T . n mod analog, deoarece interschimbarea lui y cu c nu
mrete costul, diferena B(T ) B(T 00 ) este nenegativ. Astfel B(T ) B(T 00 ), ceea ce implic
B(T 00 ) = B(T ). Aadar T 00 este un arbore optim n care x i y apar ca noduri terminale frai, i
se afl pe nivelul maxim, ceea ce trebuia demonstrat.
Din lema 17.2 se deduce faptul ca procesul de construcie a unui arbore optim prin fuzionri
poate, fr a restrnge generalitatea, s nceap cu o alegere greedy a fuzionrii acelor dou
294 Capitolul 17 Algoritmi greedy

Figura 17.5 Paii algoritmului Huffman pentru frecvenele date n figura 17.3. Fiecare parte ilustreaz
coninutul cozii ordonate cresctor dup frecven. La fiecare pas, cei doi arbori cu cele mai sczute
frecvene fuzioneaz. Frunzele figurez ca dreptunghiuri ce conin un caracter i frecvena sa. Nodurile
interne figureaz ca cercuri ce conin suma frecvenelor fiilor lor. O muchie care leag un nod intern
cu fiii ei este etichetat cu 0 dac este o muchie ctre un fiu stng, respectiv cu 1 dac este ctre fiul
drept. Cuvntul de cod pentru o liter este secvena etichetelor de pe muchiile care leag rdcina de
frunza asociat caracterului respectiv. (a) Mulimea iniial de n = 6 noduri, unul pentru fiecare liter.
(b)(e) Etape intermediare. (f ) Arborele final.

caractere cu cea mai redus frecven. De ce este aceasta o alegere greedy? Putem interpreta
costul unei singure fuzionri ca fiind suma frecvenelor celor dou obiecte care fuzioneaz.
Exerciiul 17.3-3 arat cum costul total al arborelui construit este suma costurilor obiectelor
din care a fuzionat. La fiecare pas, dintre toate fuzionrile posibile, algoritmul Huffman o alege
pe aceea care determin costul minim.
Urmtoarea lem arat c problema construirii unei codificri prefix optime are proprietatea
substructurii optime.

Lema 17.3 Fie T un arbore binar complet reprezentnd o codificare prefix optim peste un
alfabet C, unde frecvena f [c] este definit pentru fiecare caracter c C. Considerm dou
caractere x i y oarecare care apar ca noduri terminale frai n T , i fie z tatl lor. Atunci,
considernd z ca un caracter avnd frecvena f [z] = f [x] + f [y], arborele T 0 = T {x, y}
reprezint o codificare prefix optim pentru alfabetul C 0 = C {x, y} {z}.
17.3. Coduri Huffman 295

Figura 17.6 O ilustrare a pasului cheie din demonstaia lemei 17.2. n arborele optim T , b i c sunt
dou dintre frunzele aflate pe cel mai de jos nivel n arbore; aceste noduri se consider frai. x i y
sunt dou frunze pe care algoritmul Huffman le fuzioneaz primele; ele apar n poziii arbitrare n T .
Frunzele b i x sunt interschimbate pentru a obine arborele T 0 . Apoi, frunzele c i y sunt interschimbate
pentru a obine arborele T 00 . Cum cele dou interschimbri nu mresc costul, arborele rezultat T 00 este
de asemenea un arbore optim.

Demonstraie. Vom arta mai nti c B(T ), costul arborelui T , poate fi exprimat n funcie de
costul B(T 0 ) al arborelui T 0 considernd costurile componente din ecuaia (17.3). Pentru fiecare
c C {x, y}, avem dT (c) = dT 0 (c), i f [c]dt (c) = f [c]dT 0 (c). Cum dT (x) = dT (y) = dT 0 (z) + 1,
avem

f [x]dT (x) + f [y]dT (y) = (f [x] + f [y])(dT 0 (z) + 1) = f [z]dT 0 (z) + (f [x] + f [y]),

de unde deducem c

B(T ) = B(T 0 ) + f [x] + f [y].

Dac T 0 reprezint o codificare prefix care nu este optim pentru alfabetul C 0 , atunci exist
un arbore T 00 ale crui frunze sunt caractere n C 0 astfel nct B(T 00 ) < B(T 0 ). Cum z este tratat
ca un caracter n C 0 , el va apare ca frunz n T 00 . Dac adugm x i y ca fiind fiii lui z n T 00 ,
atunci vom obine o codificare prefix pentru C avnd costul B(T 00 ) + f [x] + f [y] < B(T ), ceea ce
intr n contradicie cu optimalitatea lui T . Deci T 0 trebuie s fie optim pentru alfabetul C 0 .

Teorema 17.4 Procedura Huffman realizeaz o codificare prefix optim.

Demonstraie. Este imediat, din lemele 17.2 i 17.3.

Execiii
17.3-1 Demonstrai c un arbore binar care nu este complet nu poate corespunde unei codificri
prefix optime.

17.3-2 Stabilii o codificare Huffman optim pentru urmtoarea secven de frecvene bazat
pe primele 8 numere din irul lui Fibonacci
a:1 b:1 c:2 d:3 e:5 f:8 g:13 h:21
Putei generaliza rspunsul astfel nct s determinai codificarea optim cnd frecvenele sunt
primele n numere din irul lui Fibonacci?
296 Capitolul 17 Algoritmi greedy

17.3-3 Demonstrai c, pentru o codificare, costul arborelui asociat poate fi calculat, de


asemenea, ca sum peste toate nodurile interne, ale frecvenelor combinate ale celor doi fii ai
nodului respectiv.

17.3-4 Artai c pentru o codificare optim, dac sortm caracterele n ordinea necresctoare
a frecvenelor lor, lungimile cuvintelor de cod asociate sunt n ordine nedescresctoare.

17.3-5 Fie C = {0, 1, . . . , n 1} o mulime de caractere. Artai c orice codificare prefix


optimal pe C poate fi reprezentat sub forma unei secvene de 2n 1 + ndlg ne bii. (Indicaie:
Pentru a specifica structura arborelui, utilizai 2n 1 bii, conform parcurgerii acestuia.)

17.3-6 Generalizai algoritmul lui Huffman pentru cuvinte de cod ternare (adic acele cuvinte
de cod care folosesc simbolurile 0, 1 i 2) i artai c aceasta conduce la codificri ternare
optime.

17.3-7 Fie dat un fiier de date coninnd un ir de caractere de 8 bii, astfel nct toate cele
256 de caractere apar aproximativ cu aceeai frecven: frecvena maxim este mai mic dect
dublul frecvenei minime. Artai c, n acest caz, codificarea Huffman nu este mai eficient
dect utilizarea unui cod obinuit avnd lungimea fix de 8 bii.

17.3-8 Artai c de la nici o modalitate de comprimare nu se poate atepta s compacteze


un fiier care conine caractere alese aleator, reprezentate pe 8 bii, prin schimbarea unui singur
caracter. (Indicaie: Comparai numrul de fiiere cu numrul posibil de fiiere codificate).

17.4. Bazele teoretice ale metodei greedy


n aceast seciune vom prezenta teoria care st la baza algoritmilor greedy. Aceast teorie
poate fi utilizat pentru a determina cazurile n care algoritmul greedy va conduce la soluie
optim. Ea necesit cunoaterea unor structuri combinatoriale numite matroizi. Cu toate c
aceast teorie nu acoper toate cazurile pentru care se poate aplica o metod greedy (de exemplu
nu acoper problema selectrii activitilor din seciunea 17.1 sau problema codificrii Huffman
din seciunea 17.3), ea cuprinde multe cazuri de interes practic. Mai mult, aceast teorie s-a
dezvoltat ntr-un timp scurt i a fost extins pentru a acoperi ct mai multe aplicaii (a se vedea
i notele de la sfritul capitolului).

17.4.1. Matroizi
Un matroid este o pereche ordonat M = (S, I) care satisface urmtoarele condiii:

1. S este o mulime finit nevid.

2. I este o familie nevid de submuimi ale lui S, numite submulimi independente ale lui
S, astfel nct dac B I i A B, atunci A I. Spunem c I este ereditar dac
satisface aceast proprietate. S observm c mulimea vid este automat un element al
lui I.
17.4. Bazele teoretice ale metodei greedy 297

3. Dac A I, B I i |A| < |B| atunci exist un element x B a astfel nct A{x} I.
Spunem c M satisface proprietatea de schimb.

Cuvntul matroid a fost introdus de Hassel Whitney. El a studiat matroizii matriceali ,


n care elementele lui S sunt liniile dintr-o matrice dat i o mulime de linii este independent
dac liniile din mulime sunt liniar independente n sensul uzual. Este uor de artat c aceast
structur definete un matroid (vezi exerciiul 17.4-2).
Un alt exemplu de matroid este urmtorul: considerm matroidul grafic MG = (SG , IG )
definit n termenii unui graf neorientat G = (V, E) dup cum urmeaz:

Mulimea SG este mulimea E a muchiilor grafului G.

Dac A este o submulime a lui E atunci A IG dac i numai dac A nu are cicluri.
Aceasta nseamn c o mulime de muchii este independent dac i numai dac formeaz
o pdure.

Matroidul grafic este strns legat de problema arborelui de acoperire minim care este
prezentat n detaliu n capitolul 24.

Teorema 17.5 Dac G este un graf neorientat, atunci MG = (SG , IG ) este un matroid.

Demonstraie. Evident SG = E este mulime finit. Mai mult, IG este ereditar deoarece o
submulime a unei pduri este o pdure. Altfel spus, eliminarea unor muchii dintr-o mulime de
muchii ce nu formeaz cicluri nu poate crea cicluri noi. Astfel, rmne de artat c MG satisface
proprietatea de schimb. S presupunem c A i B sunt pduri ale lui G i |B| > |A|. Cu alte
cuvinte, A i B sunt mulimi aciclice de muchii i B are mai multe muchii dect A.
Atunci, conform teoremei 5.2 o pdure avnd k muchii conine exact |V | k arbori. (Pentru
a arta acest lucru n alt mod se pleac cu |V | arbori i nici o muchie. Apoi fiecare muchie care
este adugat pdurii, reduce cu 1 numrul de arbori). Astfel, pdurea conine |V | |A| arbori
i pdurea B conine |V | |B| arbori.
Cum pdurea B are mai puini arbori dect A, ea trebuie s conin un arbore T cu vrfuri
aflate n arbori diferii din pdurea A. Mai mult, dearece T este conex, el trebuie s conin o
muchie (u, v) astfel nct vrfurile u i v s fie n arbori diferii din pdurea A. Cum muchia (u, v)
leag vrfuri n doi arbori diferii din pdurea A, ea poate fi adugat pdurii A fr a forma
un ciclu. Atunci, MG satisface proprietatea de schimb, ceea ce ncheie demonstraia faptului c
MG este un matroid.
Dndu-se un matroid M = (S, I), un element x / A se numete extensie a lui A I dac
x poate fi adugat la A cu pstrarea n acelai timp a independenei; aceasta nseamn c x este
o extensie a lui A dac A {x} I. Drept exemplu, s considerm un matroid grafic MG . Dac
A este o mulime independent de muchii, atunci muchia e este o extensie a lui A dac i numai
dac e nu este n A i adugarea ei la A nu creeaz un ciclu.
Dac A este o submulime independent ntr-un matroid M , spunem c A este maximal dac
nu are extensii. Aceasta nseamn c A este maximal dac nu este inclus n nici o submulime
independent mai mare a lui M . Urmtoarea proprietate este utilizat frecvent.

Teorema 17.6 Toate submulimile independente maximale dintr-un matroid au aceeai dimen-
siune.
298 Capitolul 17 Algoritmi greedy

Demonstraie. Presupunem, prin reducere la absurd, c A este o submulime independent


maximal a lui M i exist o alt submulime B a lui M cu aceleai proprieti. Atunci, din
proprietatea de schimb, rezult c A este extensibil la o mulime mai mare A {x} pentru un
x B A, ceea ce contrazice presupunerea c A este maximal.
Pentru a ilustra aceast teorem, s construim matroidul grafic MG pentru un graf conex
neorientat G. Fiecare submulime independent maximal a lui MG poate fi un arbore liber cu
exact |V | 1 muchii ce leag toate vrfurile din G. Un astfel de arbore se numete arbore de
acoperire al lui G.
Spunem c un matroid M = (S, I) este ponderat dac are asociat o funcie de ponderare w
care atribuie o pondere pozitiv w(x) fiecrui element x S. Funcia de ponderare w se extinde
la submulimile din S prin nsumare:
X
w(A) = w(x)
xA

pentru orice A S. De exemplu, dac w(e) desemneaz lungimea unei muchii e ntr-un matroid
grafic MG , atunci w(A) este lungimea total a muchiilor din A.

17.4.2. Algoritmi greedy pe un matroid ponderat


Numeroase probleme pentru care un algoritm greedy furnizeaz soluii optime pot fi formulate
astfel nct s conduc la determinarea unei submuimi independente de pondere maxim ntr-
un matroid ponderat. Cu alte cuvinte, se d un matroid ponderat M = (S, I) i se dorete
determinarea unei mulimi independente A I astfel nct w(A) s fie maximizat. Vom spune
c o astfel de submulime, independent i de pondere maxim posibil este submulimea optim
a matroidului. Deoarece ponderea w(x) a oricrui element x n S este pozitiv, o submulime
optim este ntotdeauna o submulime maximal independent. Este util ca A s fie ct mai
mare cu putin.
De exemplu, n cazul arborelui de acoperire minim se consider un graf neorientat, conex,
G = (V, E) i o funcie lungime w astfel nct w(e) este lungimea (pozitiv) a muchiei e. (Vom
folosi termenul de lungime pentru ponderi n matroidul asociat). Se cere determinarea unei
submulimi de muchii care unete toate vrfurile i are lungime total minim. Pentru a privi
aceasta ca o problem de determinare a submulimii optime a unui matroid, s considerm
matroidul MG cu funcia de ponderare w0 , unde w0 (e) = w0 w(e) i w0 este mai mare dect
lungimea maxim a oricrei muchii. n acest matroid ponderat, toate ponderile sunt pozitive
i o submulime optim este un arbore de acoperire avnd lungimea minim n graful original.
Mai precis, fiecare submulime independent maximal A corespunde unui arbore de acoperire
i deoarece

w0 (A) = (|V | 1)w0 w(A)

pentru orice submulime independent maximal A, submulimea independent ce maximizeaz


w0 (A) trebuie s minimizeze w(A). n consecin, orice algoritm care poate gsi o submulime
optim A ntr-un matroid arbitrar poate rezolva problema arborelui de acoperire minim.
n capitolul 24 sunt prezentai algoritmi pentru problema arborelui de acoperire minim, dar
n acest paragraf vom descrie un algoritm greedy ce funcioneaz pentru orice matroid ponderat.
Algoritmul folosete ca date de intrare matroidul ponderat M = (S, I) cu o funcie asociat w
17.4. Bazele teoretice ale metodei greedy 299

de pondere pozitiv w i ntoarce o submulime optim A. n algoritmul descris n pseudocod,


vom nota componentele lui M cu S[M ] i I[M ], iar funcia de ponderare cu w. Algoritmul este
de tip greedy deoarece ia n considerare pe rnd fiecare element x S n ordinea necresctoare
a ponderilor i l adaug imediat la mulimea A deja obinut dac A {x} este independent.
Greedy(M, w)
1: A
2: ordoneaz S[M ] necresctor dup ponderile w
3: pentru fiecare x S[M ], n ordine necresctoare dup ponderea w(x) execut
4: dac A {x} I(M ) atunci
5: A A {x}
6: returneaz A

Elementele lui S sunt considerate pe rnd, n ordinea necresctoare a ponderilor. Elementul


considerat x poate fi adugat la A dac menine independena lui A. n caz contrar x este
abandonat. Deoarece mulimea vid este independent conform definiiei unui matroid, i cum
x este adugat la A doar dac A {x} este independent, prin inducie, submulimea A
este ntotdeauna independent. Deci algoritmul Greedy returneaz ntotdeauna o submulime
independent A. Vom vedea n continuare c A este o submulime de pondere maxim posibil,
deci c A este o submulime optim.
Timpul de execuie al algoritmului Greedy este uor de calculat. Fie n = |S|. Etapa de
sortare se realizeaz n O(n lg n).
Linia 4 este executat exact de n ori, o dat pentru fiecare element din S. Fiecare execuie
a liniei 4 necesit verificarea independenei mulimii A {x}. Cum fiecare astfel de verificare se
realizeaz n O(f (n)), ntregul algoritm necesit O(n lg n + nf (n)) uniti de timp.
Vom arta n cele ce urmeaz c algoritmul Greedy returneaz o submulime optim.

Lema 17.7 (Matroizii evideniaz proprietatea alegerii greedy) S presupunem c M


=(S, I) este un matroid ponderat cu o funcie de ponderare w i c S este ordonat necresctor
dup ponderi. Fie x primul element din S astfel nct {x} este independent, dac un astfel de
x exist. Dac x exist, atunci exist o submulime optim A a lui S care l conine pe x.

Demonstraie. Dac un astfel de x nu exist atunci singura submulime independent este


submulimea vid i demonstraia se ncheie. Altfel, fie B o submulime nevid, optim oarecare.
Presupunem c x / B; altfel lum A = B i demonstraia se ncheie.
Nici un element din B nu are ponderea mai mare dect w(x). S observm c y B implic
{y} este independent deoarece B I i I este ereditar. Alegerea fcut asupra lui x asigur
w(x) w(y) pentru orice y B.
Mulimea A se construiete dup cum urmeaz. Se pleac cu A = {x}. Din alegerea lui x, A
este independent. Folosind proprietatea de schimb n mod repetat, se gsete un nou element
al lui B care poate fi adugat la A pn cnd | A |=| B |, astfel nct independena lui A este
mereu pstrat. Atunci, A = B {y} {x} pentru y B i deci

w(A) = w(B) w(y) + w(x) w(B)

Deoarece B este optim, A trebuie s fie de asemenea optim i cum x A lema este demons-
trat.
300 Capitolul 17 Algoritmi greedy

Lema 17.8 Fie M = (S, I) un matroid oarecare. Dac x este un element al lui S astfel nct x
nu este o extensie a lui , atunci x nu este o extensie a nici unei submulimi independente A a
lui S.

Demonstraie. Demonstraia se face prin reducere la absurd. Presupunem c x este o extensie a


lui A dar nu a mulimii vide . Cum x este o extensie a lui A rezult c A{x} este independent.
Deoarece I este ereditar, {x} trebuie s fie independent, ceea ce contrazice presupunerea c x
nu este o extensie a lui .
Lema 17.8 arat c orice element care nu poate fi folosit la un anumit moment nu mai poate
fi folosit niciodat ulterior. De aici se deduce c algoritmul Greedy nu poate grei, trecnd
peste elementele iniiale din S care nu sunt extensii ale lui , deoarece ele nu mai pot fi niciodat
folosite.

Lema 17.9 (Matroizii pun n eviden proprietatea de substructur optimal) Fie x


primul element ales de algoritmul Greedy din S pentru matroidul ponderat M = (S, I).
Problema rmas, de determinare a unei submulimi independendente de pondere maxim care l
conine pe x, se reduce la gsirea unei submulimi independente de pondere maxim a matroidului
ponderat M 0 = (S 0 , I 0 ), unde

S 0 = {y S : {x, y} I}, I 0 = {B S {x} : B {x} I},

i funcia de ponderare pentru M 0 este funcia de ponderare pentru M restricionat la S 0 .


(Numim M 0 contracia lui M prin elementul x.)

Demonstraie. Dac A este o submulime oarecare independent de pondere maxim a lui M ,


care conine elementul x, atunci A0 = A {x} este o submulime independent a lui M 0 . Invers,
orice submulime independent A0 a lui M 0 conduce la o submulime independent A = A0 {x}
a lui M . Cum n ambele cazuri avem w(A) = w(A0 ) + w(x), o soluie de pondere maxim n M ,
care l conine pe x, conduce la o soluie de pondere maxim n M 0 i invers.

Teorema 17.10 (Corectitudinea algoritmului greedy pe matroizi) Dac M = (S, I) es-


te un matroid ponderat cu funcia de ponderare w, atunci apelul Greedy(M, w) returneaz o
submulime optim.

Demonstraie. Conform lemei 17.8 orice elemente care nu sunt considerate iniial, deoarece nu
sunt extensii ale mulimii vide , pot fi uitate definitiv, deoarece ele nu mai sunt folositoare. O
dat ce primul element x este selectat, din lema 17.7 rezult c algoritmul Greedy nu poate
grei adugnd pe x la A pentru c exist o submulime optim ce l conine pe x. n final
lema 17.9 implic faptul c problema rmas este una de determinare a unei submulimi optime
n matroidul M 0 care este contracia lui M prin x. Dup ce procedura Greedy atribuie lui A
mulimea x toi ceilali pai pot fi interpretai ca acionnd n matroidul M 0 = (S 0 , I 0 ) deoarece
B este independent n M 0 dac i numai dac B {x} este independent n M, pentru orice
mulime B I 0 . n consecin, operaiile din algoritmul Greedy vor determina o submulime
independent de pondere maxim pentru M 0 i toate operaiile din algoritmul Greedy vor gsi
o submulime independent de pondere maxim pentru M .
17.5. O problem de planificare a activitilor 301

Exerciii
17.4-1 Artai c (S, Ik ) este un matroid, unde S este o mulime finit, iar Ik este mulimea
tuturor submulimilor lui S de dimensiune cel mult k, unde k | S |.

17.4-2 ? Dndu-se o matrice T de n n numere reale, artai c (S, I) este un matroid, unde
S este mulimea coloanelor lui T i A I, dac i numai dac n A coloanele sunt liniar
independente.

17.4-3 ? Artai c dac (S, I) este un matroid, atunci i (S, I 0 ) este un matroid, unde I 0 =
{A0 : S S 0 conine mulimi maximale A I}. Aceasta nseamn c mulimile independente
maximale ale lui (S 0 , I 0 ) sunt exact complementarele mulimilor independente maximale ale lui
(S, I).

17.4-4 ? Fie S o mulime finit i fie S1 , S2 , . . . , Sk o partiie a lui S n submulimi nevide


disjuncte. Definim structura (S, I) prin condiia ca I = {A :| A Si | 1 pentru i = 1, 2, . . . , k}.
Artai c (S, I) este un matroid. Aceasta nseamn c matricea tuturor mulimilor A, care
conine cel mult un element n fiecare bloc al partiiei, determin o mulime independent de
matroizi.

17.4-5 Artai cum se transform o funcie de ponderare a unei probleme cu matroizi ponderai
cnd soluia optim dorit este o submulime independent, maximal de pondere maxim,
pentru a o aduce la o problem standard de matroizi ponderai. Argumentai c transformarea
este corect.

17.5. O problem de planificare a activitilor


O problem interesant ce poate fi rezolvat folosind matroizi este problema planificrii
optime pe un singur procesor a unor activiti care se execut ntr-o unitate de timp. Fiecare
activitate are un termen de finalizare i o penalizare care trebuie pltit dac se depete
termenul. Problema pare complicat dar poate fi rezolvat ntr-o manier surprinztor de simpl,
folosind un algoritm greedy.
O activitate ntr-o unitate de timp este o sarcin, de exemplu un program care se
execut pe un calculator, care necesit exact o unitate de timp pentru a fi ndeplinit. Dndu-se
o submulime finit S a unor astfel de activiti, o planificare pentru S este o permutare a
lui S ce specific ordinea n care aceste sarcini trebuie realizate. Prima activitate din planificare
ncepe la momentul 0 i se termin la momentul 1, cea de-a doua ncepe la momentul 1 i se
termin la momentul 2 .a.m.d.
Problema planificrii pe un singur procesor a activitilor ntr-o unitate de timp
cu termen de finalizare i penalizri are urmtoarele date de intrare:

o mulime S = {1, 2, . . . , n} de n activiti care se execut ntr-o unitate de timp;

o mulime de n ntregi reprezentnd termenele de finalizare d1 , d2 , . . . , dn astfel nct


1 di n i se presupune c activitatea i se termin la momentul di ;
302 Capitolul 17 Algoritmi greedy

o mulime de n ponderi nenegative de penalizri w1 , w2 , . . . , wn astfel nct o penalizare


Wi este utilizat numai dac activitatea i nu se termin la momentul di .

Se cere determinarea unei planificri pentru S care minimizeaz penalizarea total pentru acti-
vitatea neterminat.
Considerm o planificare dat. Spunem c o activitate este prematur n aceast planificare
dac se termin dup termenul de finalizare. n caz contrar activitatea este n timp n planificare.
O planificare arbitrar poate fi pus ntotdeauna ntr-o form prematur, n care fiecare
activitate care se termin la timp precede activitile ntrziate. S observm c dac o activitate
prematur x, urmeaz unei activiti ntrziate y atunci poziiile lui x i y pot fi schimbate fr
a afecta faptul c x este prematur i y este ntrziat.
Analog, afirmm c o planificare arbitrar poate fi ntotdeauna pus sub forma canonic,
n care activitile premature preced pe cele ntrziate i sunt planificate n ordine nedescresc-
toare a termenelor de terminare. Pentru a realiza acest lucru se pune planificarea ntr-o prim
form prematur. Apoi, atta timp ct exist dou activiti n timp i i j care se termin la
momentele k i k + 1 n planificare cu termenele dj < di , interschimbm poziia lui i cu cea a lui
j. Cum activitatea j este prematur, nainte de interschimbare, k + 1 dj . Atunci k + 1 < di
i astfel activitatea i este tot prematur dup interschimbare. Activitatea j este mutat mai
devreme n planificare, deci ea va fi de asemenea prematur dup interschimbare.
Deci, cutarea unei planificri optime se reduce la determinarea unei mulimi A de activiti
premature. O dat determinat A, putem crea planificarea curent, listnd nti elementele din
A n ordine nedescresctoare a timpilor de terminare, apoi activitile ntrziate (adic S A)
n orice ordine, producnd astfel o ordonare canonic a planificrii optime.
Spunem c mulimea A de activiti este independent dac exist o planificare pentru
aceste activiti astfel nct nici o activitate nu este ntrziat. Evident, mulimea activitilor
n timp pentru o planificare formeaz o mulime independent de activiti. Fie I mulimea
tuturor mulimilor independente de activiti.
Considerm problema determinrii independenei unei mulimi date de activiti A. Pentru
t = 1, 2, . . . n, fie Nt (A) numrul de activiti n A a cror termen de terminare este cel mult t.

Lema 17.11 Pentru orice mulime de activiti A, urmtoarele afirmaii sunt echivalente:

1. A este mulime independent.

2. pentru t = 1, 2, . . . n avem Nt (A) t.

3. dac activitile din A sunt planificate n ordinea nedescresctoare a timpilor de terminare,


atunci nici o activitate nu este ntrziat.

Demonstraie. Evident, dac exist t astfel nct Nt (A) > t, atunci nu exist nici o modalitate
de a face o planificare cu toate activitile n timp pentru A, deoarece exist mai mult de t
activiti care trebuie s se termine nainte de momentul t. Atunci (1) implic (2). Dac (2) este
adevrat atunci rezult (3): nu exist nici o modalitate de a ne bloca atunci cnd planificm
activitile n ordinea nedescresctoare a timpilor de terminare, deoarece din (2) rezult c cel
mai ndeprtat timp de terminare i este cel mult i. n sfrit, evident, (3) implic (1).
Folosind proprietatea 2 din lema 17.11 putem calcula cu uurin dac o mulime dat de
activiti este independent (vezi exerciiul 17.5-2).
17.5. O problem de planificare a activitilor 303

Activitate
1 2 3 4 5 6 7
di 4 2 4 3 1 4 6
wi 70 60 50 40 30 20 10

Figura 17.7 O instan a problemei planificrii activitilor ntr-o unitate de timp cu termen de
finalizare i penalizri pe un singur procesor

Problema minimizrii sumei de penalizare a activitilor ntrziate este aceeai cu problema


maximizrii sumei de penalizri ale activitilor premature. Urmtoarea teorem asigur corecti-
tudinea utilizrii algoritmului greedy pentru a determina o mulime independent A de activiti
cu penalizare total maxim.

Teorema 17.12 Dac S este o mulime de activiti ntr-o unitate de timp i I este mulimea
tuturor mulimilor independente de activiti, atunci sistemul corespunztor (S, I) este un
matroid.

Demonstraie. Fiecare submulime a unei mulimi independente de activiti este evident in-
dependent. Pentru a demonstra proprietatea de schimb s presupunem c B i A sunt mulimi
independente de activiti i | B |>| A |. Fie k cel mai mare timp t astfel nct Nt (B) Nt (A).
Cum Nn (B) =| B | i Nn (A) =| A |, dar | B |>| A | trebuie s avem k < n i Nj (B) > Nj (A)
pentru orice j din intervalul k + 1 j n. Atunci B conine mai multe activiti cu timpul
de terminare k + 1 dect A. Fie x o activitate n B A cu timpul de terminare k + 1. Fie
A0 = A {x}.
Artm acum, folosind proprietatea 2 din lema 17.11, c A0 trebuie s fie independent.
Pentru 1 t k avem Nt (A0 ) Nt (B) t, deoarece B este independent. Atunci A0 este
independent ceea ce ncheie demonstraia faptului c (S, I) este matroid.
Conform teoremei 17.10 putem utiliza un algoritm greedy pentru a determina o mulime
independent de pondere maxim de activiti A. Putem atunci crea o planificare optim avnd
activitile din A ca fiind activiti premature. Aceast metod este un algoritm eficient pentru
planificarea activitilor ntr-o unitate de timp cu termen de terminare i penalizri pentru un
singur procesor. Timpul de execuie este O(n2 ) folosind algoritmul Greedy deoarece fiecare
din cele O(n) verificri independente fcute de algoritm consum O(n) uniti de timp (vezi
exerciiul 17.5-2). O implementare mai rapid este dat n problema 17-3.
Figura 17.7 prezint un exemplu pentru problema planificrii activitilor ntr-o unitate de
timp cu termene de finalizare i penalizri pe un singur procesor. n acest exemplu, algoritmul
greedy selecteaz activitile 1, 2, 3 i 4, respinge activitile 5 i 6, iar n final accept activitatea
7. Planificarea optim final este

h2, 4, 1, 3, 7, 5, 6i,

care are o penalizare total egal cu w5 + w6 = 50.


304 Capitolul 17 Algoritmi greedy

Exerciii
17.5-1 Rezolvai instana problemei planificrii dat n figura 17.7 dar cu fiecare penalizare wi
nlocuit cu 80 wi .

17.5-2 Artai cum se utilizeaz proprietatea 2 din lema 17.1 pentru a determina n timpul
O(| A |) dac o mulime A de activiti este independent sau nu.

Probleme
17-1 Schimb de monede
S considerm problema schimbrii a n ceni utiliznd cel mai mic numr de monede.
a. Descriei un algoritm greedy pentru a realiza schimbul n monede de 25, 50, 2 i 1.
Demonstrai c algoritmul conduce la o soluie optim.
b. S presupunem c monedele disponibile au valorile c0 , c1 , . . . , ck pentru ntregii c > 1 i
k 1. Artai c algoritmul greedy conduce mereu la soluie optim.
c. Dai o mulime de valori de monede pentru care algoritmul greedy nu conduce la o soluie
optim.

17-2 Subgrafuri aciclice

a. Fie G = (X, E) un graf neorientat. Folosind definiia unui matroid, artai c (E, I) este
un matroid, unde A I dac i numai dac A este o submulime aciclic a lui E.
b. Matricea de inciden a unui graf neorientat G = (X, E) este o matrice M , de
dimensiuni | X | | E | astfel nct Mve = 1 dac muchia e este incident vrfului v
i Mve = 0 altfel. Argumentai c o mulime de coloane ale lui M este liniar indepenedent
dac i numai dac mulimea corespunztoare de muchii este aciclic. Utilizai apoi
rezultatul exerciiului 17.4-2 pentru a furniza o alt demonstraie a faptului c (E, I)
de la punctul a) este matroid.
c. S presupunem c o pondere nenegativ w(e) este asociat fiecrei muchii ntr-un graf
neorientat G = (X, E). Elaborai un algoritm eficient pentru a determina o submulime
aciclic a lui E de pondere total maxim.
d. Fie G = (V, E) un graf orientat oarecare i fie (E, I) definit astfel nct A I dac i
numai dac A nu conine cicluri directe. Dai un exemplu de graf orientat G astfel nct
sistemul asociat (E, I) nu este un matroid. Specificai ce condiie din definiia unui matroid
nu este ndeplinit.
e. Matricea de inciden pentru un graf orientat G = (V, E) este o matrice M de
dimensiuni | V | | E | astfel nct Mve = 1 dac muchia e pleac din vrful v,
Mve = 1 dac muchia e intr n vrful v i Mve = 0 altfel. Argumentai c dac o mulime
de muchii ale lui G este liniar independent atunci mulimea corespunztoare de muchii
nu conine cicluri orientate.
Note bibliografice 305

f. n exerciiul 17.4-2 se afirm c mulimea mulimilor liniar independente ale coloanelor


oricrei matrice M formeaz un matroid. Explicai pe larg de ce rezultatele punctelor d) i
e) nu sunt n contradicie. De ce nu poate exista o coresponden perfect ntre o mulime
de muchii ca fiind aciclic i mulimea coloanelor corespunztoare ale matricei de inciden
ca fiind liniar independent.

17-3 Planificarea variaiilor


S considerm urmtorul algoritm pentru rezolvarea problemei din seciunea 17.5 a planificrii
activitilor ntr-o unitate de timp cu termene de finalizare i penalizri. Fie n intervale de timp,
iniial vide, unde un interval de timp i este perioada de timp msurat n uniti ce se termin la
momentul i. Considerm activitile n ordinea monoton descresctoare a penalizrilor. Dac la
considerarea activitii j exist un interval de timp nainte sau cel trziu la termenul de finalizare
dj al lui j care este nc liber, se atribuie activitatea j celui mai din urm astfel de interval,
ocupndu-l totodat. Dac nu exist un astfel de interval, activitatea j se atribuie celui mai din
urm interval neocupat.
a. Argumentai faptul c acest algoritm furnizeaz ntotdeauna rspunsul corect.

b. Utilizai mulimea disjunct a pdurilor, prezentat n seciunea 22.3 pentru a implementa


eficient algoritmul. Presupunei c mulimea activitilor de intrare a fost ordonat mono-
ton descresctor dup penalizri. Analizai timpul de execuie pentru aceast implemen-
tare.

Note bibliografice
Material bibliografic referitor la metoda greedy i matroizi poate fi gsit n Lawler [132] i
Papadimitriou i Steiglitz [154].
Algoritmii de tip greedy au aprut mai nti n literatura referitoare la optimizarea
combinatorial n 1971 ntr-un articol al lui Edmonds [62], cu toate c teoria matroizilor dateaz
nc din 1935, ea fiind prezentat ntr-un articol al lui Whitney [200].
Demonstraia corectitudinii algoritmului greedy pentru problema selectrii activitilor
urmeaz ideea lui Gavril [80]. Problema planificrii activitilor este studiat n Lawler [132],
Horowitz i Sahni [105] i Brassard i Bratley [33].
Codificarea Huffman a fost inventat n 1952 [107]; lucrrile lui Lelewer i Hirschberg [136]
despre tehnici de compactare a datelor sunt cunoscute din 1987.
O extensie a teoriei matroizilor la teoria greedoizilor a fost introdus de Korte i Lovsz
[127, 128, 129, 130]; ea generalizeaz teoria prezentat n acest capitol.
18 Analiza amortizat

ntr-o analiz amortizat timpul necesar execuiei unei secvene de operaii asupra unei
structuri de date este msurat, n medie, pentru toate operaiile efectuate. Analiza amortizat
poate fi folosit pentru a arta c, determinnd media pentru o secven de operaii, costul
unei operaii este mic, chiar dac o anume operaie este costisitoare. Analiza amortizat difer
de analiza pentru cazul mediu prin faptul c nu este luat n calcul probabilitatea; o analiz
amortizat garanteaz performana medie a fiecrei operaii pentru cazul cel mai defavorabil.
Primele trei seciuni din acest capitol prezint cele mai uzuale trei tehnici folosite n analiza
amortizat. Seciunea 18.1 ncepe cu metoda de agregare n care se determin o margine
superioar T (n) a costului total al unei secvene de n operaii. Costul amortizat pe operaie
va fi deci T (n)/n.
n seciunea 18.2 se prezint metoda de cotare, n care se determin costul amortizat al fie-
crei operaii. Dac exist mai multe tipuri de operaii, fiecare astfel de tip poate avea un cost
de amortizare distinct. Metoda de cotare supracoteaz unele operaii la nceputul secvenei, me-
mornd supracotarea ca pe un credit pltit de la nceput pentru anumite obiecte din structura
de date. Acest credit este folosit ulterior pentru operaii care sunt cotate sub costul lor real.
n seciunea 18.3 se prezint metoda de potenial, asemntoare cu metoda de cotare prin
faptul c se determin costul amortizat pentru fiecare operaie, iar la nceput operaiile pot fi
supracotate pentru a compensa subcotrile ulterioare. Metoda de potenial pstreaz creditul
drept energie potenial a structurii de date, n loc s l asocieze obiectelor individuale din
structura de date.
Pentru ilustrarea celor trei metode vor fi prezentate dou exemple. Primul se refer la o
stiv cu operaia suplimentar Scoatere-Multipl-Din-Stiv, care poate extrage mai multe
obiecte din stiv. Al doilea este un contor binar care numr ncepnd de la 0 prin intermediul
unicei operaii Incrementeaz.
Trebuie reinut c, peste tot n acest capitol, cotrile asociate n cadrul analizei amortizate
sunt fcute doar pentru aceast analiz. Ele nu vor aprea n programe. Dac, de exemplu, un
credit este asociat obiectului x n cadrul analizei amortizate, aceasta nu nseamn c n program
va apare vreo variabil credit[x].
Aplicarea analizei amortizate pentru o structur de date particular poate servi la optimizarea
proiectrii. Astfel, n seciunea 18.4 vom folosi metoda de potenial pentru analiza tabelelor care
i mresc i i micoreaz dinamic dimensiunile.

18.1. Metoda de agregare


n metoda de agregare a analizei amortizate, vom arta c, pentru orice n, o secven
de n operaii necesit timpul T (n) n cazul cel mai defavorabil. Drept urmare, n cazul cel mai
defavorabil, costul mediu pe operaie, numit i cost amortizat, va fi T (n)/n. S remarcm
c acest cost amortizat se aplic fiecrei operaii, chiar dac n secven apar mai multe tipuri
de operaii. Celelalte dou metode studiate n acest capitol (metoda de cotare i metoda de
potenial) pot asocia costuri de amortizare diferite la tipuri de operaii diferite.
18.1. Metoda de agregare 307

Figura 18.1 Modul de aciune al lui Scoatere-Multipl-Din-Stiv pe o stiv S, al crei coninut


iniial apare n (a). Scoatere-Multipl-Din-Stiv(S, 4) extrage 4 obiecte din vrful stivei, al crei
coninut devine cel din (b). Urmtoarea operaie este Scoatere-Multipl-Din-Stiv(S, 7), care
conduce la stiva vid - vezi (c) - deoarece n stiv rmseser mai puin de 7 obiecte
.

Operatori de stiv
Ca prim exemplu pentru metoda de agregare, vom analiza stive pentru care se adaug o
nou operaie. n seciunea 11.1 au fost introdui cei doi operatori de stiv fundamentali, fiecare
necesitnd timpul O(1):
Pune-n-Stiv(S, x) introduce n stiva S obiectul x;
Scoate-Din-Stiv(s) extrage un obiect din vrful stivei S i l returneaz ca rezultat.
Cum fiecare dintre aceti operatori necesit un timp O(1), costul fiecruia va fi considerat egal
cu 1. De aceea, costul total al unei secvene de n operaii Pune-n-Stiv i Scoate-Din-Stiv
este n, iar timpul real pentru execuia a n operatori este (n).
Lucrurile devin mai interesante dac adugm operatorul Scoatere-Multipl-Din-
Stiv(S, k) care extrage k obiecte din vrful stivei S; dac stiva are mai puin de k obiecte,
este extras ntreg coninutul stivei. n urmtorul algoritm scris n pseudocod, operatorul Stiv-
Vid returneaz adevrat dac stiva este vid, respectiv fals n caz contrar.
Scoatere-Multipl-Din-Stiv(S, k)
1: ct timp nu Stiv-Vid(S) i k 6= 0 execut
2: Scoate-Din-Stiv(S)
3: k k1

n figura 18.1 este prezentat un exemplu de Scoatere-Multipl-Din-Stiv.


Care este timpul de execuie pentru operatorul Scoatere-Multipl-Din-Stiv(S, k)
pentru o stiv cu s obiecte? Timpul real de execuie este liniar n numrul de operaii Scoate-
Din-Stiv efectiv executate, deci este suficient s analizm operatorul Scoatere-Multipl-
Din-Stiv n funcie de costul abstract 1 asociat fiecruia dintre operatorii Pune-n-Stiv
i Scoate-Din-Stiv. Numrul de iteraii din ciclul pentru este numrul minim min(s, k) al
obiectelor extrase din stiv. La fiecare iteraie, n linia 2 are loc un apel Scoate-Din-Stiv.
Ca urmare, costul total pentru Scoatere-Multipl-Din-Stiv este min(s, k), iar timpul de
execuie real este o funcie liniar n acest cost.
S analizm acum o secven de n operatoii Pune-n-Stiv, Scoate-Din-Stiv i
Scoatere-Multipl-Din-Stiv pentru o stiv iniial vid. n cazul cel mai defavorabil, costul
unui operator Scoatere-Multipl-Din-Stiv din secven este O(n) deoarece mrimea stivei
este cel mult n. De aceea, n cazul cel mai defavorabil, timpul este O(n) i, drept urmare,
308 Capitolul 18 Analiza amortizat

costul unei secvene de n operatori este O(n2 ), deoarece pot exista un numr de O(n) operatori
Scoatere-Multipl-Din-Stiv, fiecare avnd costul O(n). Dei aceast analiz este corect,
rezultatul O(n2 ) obinut, considernd costul n cazul cel mai defavorabil pentru fiecare operator
n parte, poate fi mbuntit.
Prin utilizarea metodei de agregare a analizei amortizate, putem obine o margine superioar
mai bun prin considerarea ntregii secvene de n operatori. ntr-adevr, dei o operaie
Scoatere-Multipl-Din-Stiv poate fi costisitoare, orice secven de n operaii Pune-n-
Stiv, Scoate-Din-Stiv i Scoatere-Multipl-Din-Stiv plecnd de la stiva vid poate
avea cel mult costul O(n). De ce? Fiecare obiect poate fi extras cel mult o dat dup introdu-
cerea sa. De aceea, numrul de apeluri Scoate-Din-Stiv, pentru stiv nevid, inclusiv ape-
lurile cuprinse n Scoatere-Multipl-Din-Stiv, este cel mult egal cu numrul de operaii
Pune-n-Stiv, care este cel mult n. Pentru orice n, orice secven de n operatori Pune-
n-Stiv, Scoate-Din-Stiv i Scoatere-Multipl-Din-Stiv va avea costul total O(n).
Costul amortizat al unui operator va fi media corespunztoare: O(n)/n = O(1).
Precizm din nou c, dei timpul de execuie i costul mediu al unui operator de stiv este
O(1), nu s-a folosit un raionament probabilist. Am determinat o margine O(n) pentru cazul cel
mai defavorabil pentru o secven de n operatori. mprind acest cost total la n, am obinut
costul mediu pe operator, adic tocmai costul amortizat.

Un contor binar pentru incrementare


Pentru nc o exemplificare a metodei de agregare, vom considera un contor binar pe k
bii care i incrementeaz valoarea, plecnd de la 0. Vom folosi un tablou de bii A[0..k 1]
pentru acest contor; lungime[A] = k. Un numr binar x memorat n contor are cifra cea mai
nesemnificativ memorat n A[0], i cea mai semnificativ memorat n A[k 1], astfel nct
Pk1
x = i=0 A[i] 2i . Iniial x = 0, deci A[i] = 0 pentru orice i = 0, 1, . . . , k 1. Pentru a mri cu
o unitate (modulo 2k ) valoarea contorului, folosim urmtoarea procedur:
Incrementeaz(A)
1: i 0
2: ct timp i < lungime[A] i A[i] = 1 execut
3: A[i] 0
4: ii+1
5: dac i < lungime[A] atunci
6: A[i] 1

Acest algoritm este, n esen, cel implementat n hardware de un contor ripple-carry (vezi
seciunea 29.2.1). Figura 18.2 arat cum un contor binar este incrementat de 16 ori, plecnd
de la valoarea iniial 0 i terminnd cu valoarea 16. La nceputul fiecrei iteraii a ciclului ct
timp, n liniile 24 dorim s adunm 1 pe poziia i. Dac A[i] = 1, atunci, prin adunarea lui 1,
bitul de pe poziia i devine 0 i se obine cifra de transport 1, care va fi adunat pe poziia i + 1
la urmtoarea iterare a ciclului. n caz contrar, ciclul se termin; dac i < k, tim c A[i] = 0,
astfel nct adugarea lui 1 pe poziia i, comutnd 0 n 1, se realizeaz pe linia 6. Costul fiecrei
operaii Incrementeaz este liniar n numrul de bii a cror valoare a fost comutat.
Asemntor exemplului cu stiva, o analiz brut produce o margine care este corect, dar nu
suficient de bun. O singur execuie a lui Incrementeaz are, n cazul cel mai defavorabil,
18.1. Metoda de agregare 309

Figura 18.2 Configuraia unui contor binar pe 8 bii a crui valoare crete de la 0 la 16 ca urmare a
16 operaii Incrementeaz. Biii evideniai sunt cei care sunt afectai la obinerea urmtoarei valori
a contorului. Costul msurat n numrul de bii care i schimb valoarea, este scris n dreapta. Este de
remarcat c valoarea costului total nu depete de dou ori numrul total de operaii Incrementeaz.

timpul (k), corespunztor situaiei n care toate componentele lui A sunt egale cu 1. Ca urmare,
o secven de n operaii Incrementeaz, plecnd de la valoarea iniial 0 a contorului, necesit
n cazul cel mai defavorabil timpul O(nk).
Putem mbunti analiza i obine costul O(n) n cazul cel mai defavorabil pentru o secven
de n operaii Incrementeaz, observnd c nu toi biii comut (i schimb valoarea din 0
n 1 sau invers) la fiecare apel al procedurii Incrementeaz. Aa cum se arat n figura 18.2,
A[0] comut la fiecare apel al procedurii Incrementeaz. Bitul A[1] comut la fiecare dou
incrementri: o secven de n operaii Incrementeaz, pentru un contor iniial egal cu zero, face
ca A[1] s comute de bn/2c ori. Similar, bitul A[2] comut la fiecare patru Incrementeazri,

deci de bn/4c ori. Mai general, pentru i = 0, 1, . . . , blg nc, bitul A[i] comut de n/2i ori ntr-o
secven de n operatori Incrementeaz pentru un contor binar cu valoarea iniial 0. Pentru
i > blg nc, bitul A[i] nu comut niciodat. Numrul de comutri pentru secven este, ca urmare:

blg nc j
nk
X X
1
i
< n = 2n,
i=0
2 i=0
2i

conform ecuaiei (3.4). Rezult c, pentru o secven de n operatori Incrementeaz pentru


un contor binar cu valoarea iniial zero, timpul, n cazul cel mai defavorabil, este O(n) i, prin
urmare, costul amortizat al fiecrei operaii este O(n)/n = O(1).
310 Capitolul 18 Analiza amortizat

Exerciii
18.1-1 Dac am include un operator Inserare-Multipl-n-Stiv printre operatorii de stiv,
s-ar pstra marginea O(1) pentru costul amortizat al operaiilor pe stiv?

18.1-2 Artai c, dac s-ar include un operator Decrement n exemplul cu contorul binar pe
k bii, n operaii ar putea necesita timpul (nk).

18.1-3 Considerm o secven de n operaii ce se execut pe o structur de date. Presupunem


c operaia i are costul i dac i este o putere a lui 2, respectiv, are costul egal cu 1 n caz contrar.
Aplicai o metod de agregare pentru a determina costul de amortizare pe operaie.

18.2. Metoda de cotare


n metoda de cotare a analizei amortizate, atribuim operaiilor diferite, cotri diferite,
unele unele operaii fiind supracotate sau subcotate fa de costul real. Valoarea cu care cotm o
operaie se numete costul amortizat. Cnd costul amortizat al unei operaii depete costul
real, diferena este atribuit la anumite obiecte din structura de date drept credit. Acest credit
poate fi folosit mai trziu pentru a ajuta s pltim pentru operaiile al cror cost amortizat este
mai mic dect costul lor real. Astfel, putem considera costul amortizat al unei operaii ca fiind
format din costul real i creditul, care este fie depozitat, fie folosit. Aici apare deosebirea fa de
metoda de agregare, n care toate operaiile au acelai cost amortizat.
Costurile amortizate ale operaiilor trebuie alese cu grij. Dac dorim ca analiza cu costuri
amortizate s evidenieze c, n cel mai defavorabil caz, costul mediu pe operaie este mic, costul
amortizat total al unei secvene de operaii trebuie s fie o margine superioar pentru costul
real total al secvenei. Mai mult, la fel ca n metoda de agregare, aceast relaie trebuie s aib
loc pentru toate secvenele de instruciuni. n acest mod, creditul total asociat structurii de
date trebuie s fie, n permanen, nenegativ, deoarece reprezint cantitatea cu care costurile
amortizate totale depesc costurile reale totale. Dac s-ar admite valori negative pentru creditul
total (ca rezultat al subcotrii iniiale a operaiilor, n sperana de a returna acest aconto mai
trziu), atunci costurile amortizate totale suportate la acel moment ar fi sub costurile totale
reale suportate; pentru secvena de operaii pn la acel moment, costul total amortizat nu va
constitui o margine superioar pentru costul real total. De aceea, trebuie s avem grij ca n
structura de date creditul s nu devin negativ.

Operaii de stiv
Pentru a ilustra metoda de cotare a analizei amortizate, s ne ntoarcem la exemplul referitor
la stive. Reamintim costurile reale ale operaiilor:

Pune-n-Stiv 1,
Scoate-Din-Stiv 1,
Scoatere-Multipl-Din-Stiv min(k, s),
18.2. Metoda de cotare 311

unde k este argumentul furnizat la apelarea subprogramului Scoatere-Multipl-Din-Stiv,


iar s este mrimea stivei la apelare. Vom ataa urmtoarele costuri amortizate:
Pune-n-Stiv 2,
Scoate-Din-Stiv 0,
Scoatere-Multipl-Din-Stiv 0.
S remarcm c Scoatere-Multipl-Din-Stiv are drept cost amortizat o constant (0), n
timp ce costul real este variabil. Aici toate cele trei costuri amortizate sunt de ordinul O(1), dei,
n general, costurile amortizate ale operaiilor considerate pot s difere asimptotic.
Vom arta n continuare c vom putea plti pentru orice secven de operaii de stiv prin
cotarea costurilor amortizate. Presupunem c vom folosi o hrtie de 1$ pentru fiecare unitate
de cost. Pornim cu stiva vid. S ne reamintim de analogia din seciunea 11.1 ntre structura de
date stiv i un vraf de farfurii. Cnd adugm o farfurie n stiv, pltim 1$ pentru costul real al
adugrii n stiv i rmnem cu un credit de 1$ (din cei 2$ cotai) pe care l punem pe farfurie.
La orice moment de timp, pe fiecare farfurie din stiv apare creditul de 1$.
Dolarul depus pe farfurie este o plat anticipat pentru costul extragerii ei din stiv. La
execuia unei operaii Scoate-Din-Stiv, cotm operaia cu 0 i pltim costul ei real folosind
creditul depus pe stiv. Pentru a extrage o farfurie, lum dolarul de pe acea farfurie i l folosim
pentru a plti costul real al operaiei. Astfel, cotnd un pic mai mult operaia Pune-n-Stiv,
nu trebuie s cotm cu ceva operaia Scoate-Din-Stiv.
Mai mult, nu trebuie s mai cotm cu ceva operaiile Scoatere-Multipl-Din-Stiv.
Pentru a extrage prima farfurie, lum dolarul aflat pe ea i l folosim pentru a plti costul real
al operaiei Scoate-Din-Stiv. Pentru a extrage a doua farfurie, avem din nou la dispoziie un
credit de 1$ pe farfurie pentru a plti operaia Scoate-Din-Stiv i aa mai departe. n acest
mod am cotat (pltit) suficient nainte de a executa operaii Scoatere-Multipl-Din-Stiv.
Cu alte cuvinte, cum fiecare farfurie din stiv are pe ea un credit de 1$ i cum stiva conine un
numr nenegativ de farfurii, ne-am asigurat c valoarea creditului este ntotdeauna nenegativ.
Astfel, pentru orice secven de n operaii Pune-n-Stiv, Scoate-Din-Stiv i Scoatere-
Multipl-Din-Stiv, costul total amortizat este o margine superioar a costului real total.
Cum costul amortizat total este O(n), costul real total are acelai ordin de mrime.

Incrementarea unui contor binar


Ca o a doua ilustrare a metodei de cotare, vom analiza aciunea operaiei Incrementeaz
asupra unui contor binar iniializat cu zero. Aa cum s-a artat mai sus, timpul de execuie al
acestei operaii este proporional cu numrul de bii ce comut; acest numr va fi folosit drept
cost pentru acest exemplu. Vom folosi, din nou, o hrtie de 1$ pentru a reprezenta fiecare unitate
de cost (comutarea unui bit n cazul nostru).
Pentru analiza amortizat vom cota cu 2$, drept cost amortizat, setarea unui bit pe 1. La
setarea unui bit, vom folosi 1$ (din cei 2$) pentru a plti setarea efectiv a bitului i vom plasa
cellalt dolar pe bit, drept credit. n fiecare moment, fiecrui 1 din contorul binar i s-a asociat un
credit de 1$, astfel nct nu trebuie pltit nimic pentru resetarea bitului pe 0: pltim resetarea
cu dolarul aflat pe bit.
Putem determina acum costul amortizat al subprogramului Incrementeaz. Costul resetrii
biilor n cadrul ciclului ct timp este pltit cu dolarii aflai pe biii care sunt resetai. Cel mult
un bit este setat, pe linia 6 a procedurii Incrementeaz, i, prin urmare, costul amortizat al
312 Capitolul 18 Analiza amortizat

unei operaii Incrementeaz este de cel mult 2 dolari. Deoarece numrul de 1 din contor nu
este niciodat negativ, suma de credit este ntotdeauna nenegativ. Rezult, c pentru n operaii
Incrementeaz, costul amortizat total este O(n), care mrginete costul real total.

Exerciii
18.2-1 Se efectueaz n operaii asupra unei stive a crei mrime este ntotdeauna cel mult egal
cu k. Dup fiecare k operaii, se copiaz ntreaga stiv n scopul salvrii ei. Artai c, pentru
n operaii de stiv, inclusiv salvarea ei, costul este O(n) dac stabilim n mod judicios costuri
amortizate pentru diferitele operaii de stiv.

18.2-2 Reluai exerciiul 18.1-3 folosind metoda de cotare.

18.2-3 S presupunem c dorim nu doar s incrementm contorul, dar s l i resetm la zero


(adic s iniializm toi biii cu 0). Artai cum poate fi implementat un contor sub forma unui
vector de bii, astfel nct orice secven de n operaii Incrementeaz i Reset s necesite
timpul O(n), presupunnd c iniial contorul este zero. (Indicaie: Folosii un pointer la cifra cea
mai semnificativ egal cu 1.)

18.3. Metoda de potenial


n loc de a considera efortul pltit la nceput, sub forma unui credit repartizat anumitor
obiecte din structura de date, metoda de potenial a analizei amortizate trateaz acest efort
ca energie potenial sau, pe scurt, potenial. Acesta va fi folosit pentru a plti urmtoarele
operaii. Potenialul este asociat structurii de date considerat ca un tot, n loc s fie repartizat
anumitor obiecte din structura de date.
Descriem, n continuare, cum lucreaz metoda de potenial. Plecm de la o structur de date
iniial D0 asupra creia se execut n operaii. Pentru fiecare i = 1, 2, . . . , n, fie ci costul real al
operaiei i i fie Di structura de date obinut din Di1 dup aplicarea operaiei i. O funcie
de potenial ataeaz fiecrei structuri de date Di numrul real (Di ), care este potenialul
asociat structurii de date Di . Costul amortizat cbi al operaiei i pentru funcia de potenial
este definit prin
cbi = ci + (Di ) (Di1 ). (18.1)
Prin urmare, costul amortizat al fiecrei operaii este costul real plus creterea de potenial
datorat operaiei. Conform ecuaiei (18.1), costul amortizat total al celor n operaii este:
n
X n
X n
X
cbi = (ci + (Di ) (Di1 )) = ci + (Dn ) (D0 ). (18.2)
i=1 i=1 i=1

A doua relaie rezult din ecuaia (3.7), deoarece (Di ) telescopeaz.


Dac putemP defini o funcie de potenial , astfel nct (Dn ) (D0 ), atunci costul
n
amortizat total i=1 cbi este o margine superioar pentru costul real total. n practic, nu tim
ntotdeauna cte operaii vor fi efectuate. De aceea, dac cerem ca (Di ) (D0 ) pentru orice
i, atunci garantm, ca n metoda de cotare, c pltim n avans. De multe ori, este convenabil s
18.3. Metoda de potenial 313

definim (D0 ) ca fiind 0 i s artm c (Di ) 0 pentru toi i. (Vezi exerciiul 18.3-1 pentru
a deprinde un mod simplu de tratare a cazurilor n care (D0 ) 6= 0).
Intuitiv, dac diferena de potenial (Di )(Di1 ) a operaiei i este pozitiv, atunci costul
amortizat cbi reprezint o supracotare a operaiei i, iar potenialul structurii de date crete. Dac
diferena de potenial este negativ, atunci costul amortizat reprezint o subcotare a operaiei
i, iar costul real al operaiei este pltit prin descreterea potenialului.
Costurile amortizate definite de ecuaiile (18.1) i (18.2) depind de alegerea funciei de
potenial . Funcii de potenial diferite pot conduce la costuri amortizate diferite, care rmn
ns margini superioare ale costurilor reale. De multe ori are loc o negociere la alegerea funciei
de potenial: cea mai bun funcie de potenial depinde de limitele de timp dorite.

Operaii de stiv
Pentru ilustrarea metodei de potenial, ne ntoarcem din nou la exemplul cu operatorii de
stiv Pune-n-Stiv, Scoate-Din-Stiv i Scoatere-Multipl-Din-Stiv. Definim funcia
de potenial pe stiv ca fiind numrul de obiecte din stiv. Pentru stiva vid, de la care se
pleac, avem (D0 ) = 0. Deoarece numrul de elemente din stiv nu este niciodat negativ, stiva
Di la care se ajunge dup operaia i are un potenial nenegativ i, ca urmare,

(Di ) 0 = (D0 ).

Rezult c pentru n operaii costul amortizat total n raport cu reprezint o margine superioar
a costului real.
Calculm, n continuare, costurile amortizate ale diferitelor operaii de stiv. Dac operaia
i este efectuat pe o stiv coninnd s obiecte i are tipul Pune-n-Stiv, atunci diferena de
potenial este

(Di ) (Di1 ) = (s + 1) s = 1.

Conform ecuaiei (18.1), costul amortizat al operaiei Pune-n-Stiv este

cbi = ci + (Di ) (Di1 ) = 1 + 1 = 2.

S presupunem acum c operaia i efectuat pe stiv este Scoatere-Multipl-Din-Stiv(S, k)


i c un numr de k 0 = min(k, s) obiecte sunt extrase din stiv. Costul real al operaiei este k 0 ,
iar diferena de potenial este

(Di ) (Di1 ) = k 0 .

Deci costul amortizat al operaiei Scoatere-Multipl-Din-Stiv este

cbi = ci + (Di ) (Di1 ) = k 0 k 0 = 0.

n mod analog, obinem un cost amortizat egal cu 0 pentru o operaie Scoate-Din-Stiv.


Costurile amortizate ale fiecreia dintre cele trei operaii este O(1) i, deci, costul amortizat
total al unei secvene de n operaii este O(n). Deoarece tim c (Di ) (D0 ), costul amortizat
total a n operaii constituie o margine superioar pentru costul real total. Costul celor n operaii,
n cazul cel mai defavorabil, este egal cu O(n).
314 Capitolul 18 Analiza amortizat

Incrementarea contorului binar


Pentru a prezenta nc un exemplu de aplicare a metodei de potenial, vom considera din
nou problema incrementrii unui contor binar. De aceast dat vom defini potenialul contorului
dup i operaii Incrementeaz ca fiind bi = numrul de cifre 1 din contor dup operaia i.
S calculm acum costul amortizat al operaiei Incrementeaz. S presupunem c cea de
a i-a operaie Incrementeaz reseteaz ti bii. Costul real al operaiei este cel mult ti + 1
deoarece, pe lng resetarea a ti bii, este setat la 1 cel mult un bit. Numrul de cifre 1 din
contor, dup a i-a operaie Incrementeaz, este egal cu bi bi1 ti + 1, iar diferena de
potenial este

(Di ) (Di1 ) (bi1 ti + 1) bi1 = 1 ti .

Drept urmare, costul amortizat este

cbi = ci + (Di ) (Di1 ) (ti + 1) + (1 ti ) = 2.

Contorul pornete de la zero, deci (D0 ) = 0. Cum (Di ) 0 pentru orice i, costul amortizat
total al unei secvene de n operaii Incrementeaz este o margine superioar pentru costul
real total; rezult c, n cazul cel mai defavorabil, costul a n operaii Incrementeaz este O(n).
Metoda de potenial ne furnizeaz o modalitate simpl de analiz a contorului chiar i n cazul
n care acesta nu pornete de la zero. Iniial, exist b0 de 1, iar dup n operaii Incrementeaz
sunt bn de 1, unde 0 b0 , bn k. Putem rescrie ecuaia (18.2) astfel
n
X n
X
ci = cbi (Dn ) + (D0 ). (18.3)
i=1 i=1

Avem cbi 2 pentru orice 1 i n. Cum (D0 ) = b0 i (Dn ) = bn , costul real total a n
operaii Incrementeaz este
n
X n
X
ci 2 bn + b0 = 2n bn + b0 .
i=1 i=1

n particular, innd cont de faptul c b0 k, dac executm cel puin n = (k) operaii
Incrementeaz, costul real total va fi O(n), indiferent de valoarea iniial a contorului.

Exerciii
18.3-1 Fie o funcie de potenial cu (Di ) (D0 ) pentru orice i, dar (D0 ) 6= 0. Artai c
exist o funcie de potenial 0 astfel nct 0 (D0 ) = 0, 0 (Di ) 0 pentru orice i 1, iar costurile
amortizate corespunztoare lui 0 sunt aceleai ca i costurile amortizate corespunztoare lui .

18.3-2 Reluai exerciiul 18.1-3 folosind pentru analiz o metod de potenial.

18.3-3 S considerm o structur de date de tip ansamblu binar cu n elemente, pentru care
instruciunile Insereaz i Extrage-Minim cer timpul O(lg n) n cazul cel mai defavorabil.
Determinai o funcie de potenial astfel nct costul amortizat al procedurii Insereaz este
O(lg n), costul amortizat al procedurii Extrage-Minim este O(1) i demonstrai acest lucru.
18.4. Tabele dinamice 315

18.3-4 Care este costul total al execuiei a n operaii Pune-n-Stiv, Scoate-Din-Stiv i


Scoatere-Multipl-Din-Stiv pentru o stiv care conine iniial s0 obiecte, iar n final sn
obiecte?
18.3-5 S considerm un contor care nu pornete de la 0, ci pleac de la un numr a crui
reprezentare n baza 2 conine b de 1. Artai c, pentru execuia a n operaii Incrementeaz
costul este O(n) dac n = (b). (Valoarea b nu trebuie considerat ca fiind o constant.)
18.3-6 Artai cum poate fi implementat o coad folosind dou stive (exerciiul 11.1-6), astfel
nct costul amortizat al fiecrei operaii Pune-n-Coad i a fiecrei operaii Scoate-Din-
Coad s fie O(1).

18.4. Tabele dinamice


n unele aplicaii, nu tim de la nceput cte obiecte vor fi memorate ntr-un tablou. Alocnd
un anumit spaiu pentru tablou, riscm s descoperim mai trziu c acest spaiu este insuficient.
Trebuie s facem o realocare pentru un nou tablou de dimensiuni mai mari i s copiem toate
elementele din tabloul iniial n tabloul nou creat. n mod similar, dac mai multe obiecte au
fost terse dintr-un tablou, poate fi convenabil s crem un nou tablou, de dimensiuni mai mici,
i s copiem tabloul curent n cel nou creat. n aceast seciune vom studia problema mririi
(expandrii) i micorrii (comprimrii) dinamice a unui tablou. Folosind analiza amortizat
vom arta c, pentru inserare i tergere, costul este O(1), chiar i atunci cnd costul real al
unei operaii este mai mare, atunci cnd are loc o mrire sau o micorare a dimensiunilor. De
asemenea vom arta cum se poate garanta c spaiul nefolosit dintr-un tablou dinamic nu va
depi o subdiviziune constant a spaiului total.
Vom presupune c tabloul dinamic permite operaiile Insereaz-Tablou i terge-
Tablou. Operaia Insereaz-Tablou insereaz n tablou un articol care ocup o singur
locaie, adic spaiul necesar memorrii unui articol. n mod analog, operaia terge-Tablou
poate fi gndit ca fiind ndeprtarea unui articol din tablou, elibernd astfel o locaie. Detaliile
referitoare la structura de date folosit pentru organizarea tabloului nu au aici importan: putem
folosi o stiv (seciunea 11.1), un ansamblu (seciunea 7.1) sau un tabel de dispersie (capitolul
12). Putem, de asemenea, s folosim un vector sau o colecie de vectori pentru a implementa
memorarea obiectelor, aa cum s-a procedat n seciunea 11.
Este convenabil s folosim un concept introdus n analiza dispersiei (capitolul 12). Definim
factorul de ncrcare (T ) al unui tablou T nevid ca fiind numrul de articole memorate n
tablou, mprit la dimensiunea (numrul de locaii ale) tabloului. Tabloul vid (cu nici un articol)
are dimensiunea 0 i definim factorul su de ncrcare ca fiind 1. Dac factorul de ncrcare al unui
tablou dinamic este mrginit inferior de o constant, spaiul nefolosit din tablou nu depete
niciodat o subdiviziune constant a dimensiunii spaiului total.
ncepem prin a analiza un tablou dinamic asupra cruia se execut numai operaii de inserare.
Vom trece apoi la cazul general n care sunt permise att inserri, ct i tergeri.

18.4.1. Expandarea tabloului


Presupunem c pentru alocarea memoriei pentru un tablou se folosete un vector de locaii.
Un tablou este considerat plin dac toate locaiile sale au fost folosite, adic atunci cnd factorul
316 Capitolul 18 Analiza amortizat

su de ncrcare este 1.1 n unele medii software, dac se face o ncercare de a introduce un articol
ntr-un tablou plin, singura alternativ posibil este de a termina programul, mpreun cu afiarea
unui mesaj de eroare. Vom presupune aici c lucrm ntr-un mediu modern care dispune de un
sistem de gestiune a memoriei, care poate aloca i elibera, la cerere, blocuri de memorie. Astfel,
atunci cnd se ncearc inserarea unui articol ntr-un tablou plin, putem expanda (mri) tabloul
prin alocarea unui nou tablou cu mai multe locaii dect cel curent i prin copierea elementelor
din tabloul curent n cel nou.
O metod euristic uzual este de a aloca un nou tablou, care s aib de dou ori mai
multe locaii dect precedentul. Dac se efectueaz doar inserri, factorul de ncrcare este,
ntotdeauna, cel puin egal cu 1/2 i, astfel, spaiul disponibil nu depete niciodat jumtate
din spaiul total alocat tabloului.
n pseudocodul care urmeaz, vom presupune c T este un obiect ce reprezint tabloul.
Cmpul ref [T ] conine un pointer la blocul de memorie reprezentnd tabloul. Cmpul num[T ]
conine numrul de articole din tablou, iar cmpul dim[T ] conine numrul total de articole ce
pot fi memorate n tablou. Iniial, tabloul este vid: num[T ] = dim[T ] = 0.
Insereaz-Tablou(T, x)
1: dac dim[T ] = 0 atunci
2: aloc pentru ref [T ] o locaie de memorie
3: dim[T ] 1
4: dac num[T ] = dim[T ] atunci
5: aloc pentru tablou-nou un numr de 2 dim[T ] locaii
6: insereaz toate articolele din ref [T ] n tablou nou
7: elibereaz ref [T ]
8: ref [T ] tablounou
9: dim[T ] 2 dim[T ]
10: insereaz x n ref [T ]
11: num[T ] num[T ] + 1

S observm c avem, de fapt, dou proceduri de inserare: procedura Insereaz-Tablou i


inserarea elementar n tablou, realizat n liniile 6 i 10. Putem analiza timpul de execuie al
algoritmului Insereaz-Tablou n funcie de numrul de inserri elementare, atribuind costul 1
fiecrei inserri elementare. Vom presupune c timpul de execuie real al lui Insereaz-Tablou
este liniar n funcie de timpul cerut pentru inserarea unui singur articol, astfel nct efortul
suplimentar pentru alocarea unui tablou iniial n linia 2, este constant, iar efortul suplimentar
pentru alocarea i eliberarea de memorie, n liniile 5 i 7, este mai mic dect costul transferrii
articolelor, realizat n linia 6. Vom numi expandare evenimentul care are loc atunci cnd este
executat clauza atunci din liniile 59.
S considerm acum o secven de n operaii Insereaz-Tablou efectuate asupra unui
tablou iniial vid. Care este costul ci al operaiei i? Dac mai exist loc n tabloul curent (sau
dac este vorba de prima operaie), atunci ci = 1, deoarece trebuie efectuat doar inserarea
elementar din linia 10. Dac tabloul curent este plin i deci are loc o expandare, atunci ci = i:
inserarea elementar din linia 10 are costul 1, iar cele i 1 mutri din tabloul curent n cel nou
1 n unele situaii, ca de exemplu pentru un tabel de dispersie cu adresare liber, e posibil s dorim s considerm

un tablou ca fiind plin atunci cnd factorul su de ncrcare este o constant strict mai mic dect 1. (Vezi
exerciiul 18.4-2.)
18.4. Tabele dinamice 317

creat, efectuate n linia 6, au fiecare costul 1. Dac sunt executate n operaii, costul pentru o
operaie, n cazul cel mai defavorabil, este O(n), ceea ce conduce la o margine superioar O(n2 )
pentru timpul de execuie total al celor n operaii.
Aceast margine nu este cea mai convenabil, deoarece costul expandrii tabloului nu
intervine foarte des n timpul efecturii celor n operaii Insereaz-Tablou. Mai precis, operaia
i conduce la o expandare numai dac i 1 este o putere a lui 2. Costul amortizat al unei operaii
este, de fapt, O(1), aa cum se poate arta dac folosim metoda de agregare. Costul operaiei i
este:

i dac i 1 este o putere a lui 2,
ci =
1 altfel.

Costul total a n operaii Insereaz-Tablou este prin urmare:


n blg nc
X X
ci n + 2j < n + 2n = 3n,
i=1 j=0

deoarece exist cel mult n operaii de cost 1, iar costul celorlalte operaii formeaz o progresie
geometric. Deoarece costul total a n operaii Insereaz-Tablou este 3n, costul amortizat al
unei singure operaii este 3.
Folosind metoda de cotare, ne dm seama mai uor de ce costul amortizat al unei operaii
Insereaz-Tablou este 3. Intuitiv, fiecare articol are de pltit pentru 3 inserri elementare:
inserarea propriu-zis n tablou, mutarea sa efectuat atunci cnd tabloul este expandat i
mutarea unui alt articol care a fost deja mutat o dat atunci cnd tabloul a fost expandat. De
exemplu, s presupunem c, imediat dup o expandare, dimensiunea tabloului este m. Atunci
numrul efectiv de articole este m/2 i tabloul nu conine vreun credit. Cotm cu 3 dolari fiecare
inserare. Inserarea elementar care urmeaz imediat cost 1 dolar. Un al doilea dolar este plasat
drept credit pe articolul inserat. Un al treilea dolar este plasat drept credit pe unul dintre cele
m/2 articole existente deja n tablou. Umplerea tabloului cere m/2 inserri suplimentare i, ca
urmare, la momentul n care tabloul devine plin i are deci m articole efective, fiecare articol are
plasat pe el un dolar care va fi pltit la reinserarea sa n timpul urmtoarei expandri.
Pentru analiza unei secvene de n operaii Insereaz-Tablou, putem folosi i metoda de
potenial; o vom folosi n seciunea 18.4.2 pentru proiectarea unei operaii terge-Tablou care
va avea, de asemenea, costul amortizat O(1). ncepem prin a defini o funcie de potenial (a crei
valoare este 0 imediat dup o expandare, dar crete pn la dimensiunea tabloului atunci cnd
acesta devine plin), astfel nct putem plti din potenial pentru efectuarea expandrii. Funcia

(T ) = 2 num[T ] dim[T ] (18.4)

reprezint una dintre variantele posibile. Imediat dup o expandare, avem num[T ] = dim[T ]/2 i
astfel (T ) = 0, aa cum dorim. n momentul dinaintea unei expandri, avem num[T ] = dim[T ]
i, deci, (T ) = num[T ], aa cum dorim. Valoarea iniial a potenialului este 0 i deoarece
tabloul este ntotdeauna plin cel puin pe jumtate, num[T ] dim[T ]/2, de unde rezult c
(T ) este ntotdeauna nenegativ. Prin urmare suma costurilor amortizate a celor n operaii
Insereaz-Tablou este o margine superioar pentru suma costurilor reale.
Pentru a analiza costul amortizat al celei de a i-a operaii Insereaz-Tablou, vom nota
prin numi numrul de articole memorate n tablou dup aceast operaie, prin dimi dimensiunea
318 Capitolul 18 Analiza amortizat

tabloului dup aceast operaie, iar prin i potenialul dup aceast operaie. Iniial avem
num0 = 0, dim0 = 0, 0 = 0.
Dac operaia i nu conduce la o expandare, atunci dimi = dimi1 i costul amortizat al
operaiei este

cbi = ci + i i1 = 1 + (2 numi dimi ) (2 numi1 dimi1 )


= 1 + (2 numi dimi ) (2 (numi 1) dimi ) = 3.

Dac operaia i conduce la o expandare, atunci dimi /2 = dimi1 = numi 1, iar costul amortizat
al operaiei este

cbi = ci + i i1 = numi + (2 numi dimi ) (2 numi1 dimi1 )


= numi + (2 numi (2 numi 2)) (2 (numi 1) (numi 1))
= numi + 2 (numi 1) = 3.

n figura 18.3 se arat cum variaz valorile numi , dimi i i n funcie de i. Observai modul n
care potenialul este folosit pentru a plti expandarea tabloului.

18.4.2. Expandarea i contractarea tabloului


Pentru a implementa o operaie terge-Tablou este suficient s ndeprtm articolul
specificat din tablou. Totui, uneori este de dorit s contractm tabloul atunci cnd factorul de
ncrcare devine prea mic, pentru ca spaiul nefolosit s nu fie exagerat de mare. Contractarea
tabloului este analog expandrii sale: cnd numrul de articole din tablou scade prea mult,
alocm un nou tablou, mai mic, i copiem articolele din vechiul tablou n noul tablou. Spaiul
de memorie ocupat de vechiul tablou poate fi acum eliberat prin transmiterea sa sistemului de
gestiune a memoriei. Ideal, ar trebui satisfcute ntotdeauna dou proprieti:

factorul de ncrcare al tabloului dinamic s fie mrginit inferior de o constant i

costul amortizat al unei operaii asupra tabloului s fie mrginit superior de o constant.

Vom presupune c putem msura costul n funcie de inserrile i tergerile elementare.


O strategie natural pentru expandare i contractare este cea de a dubla mrimea tabloului
atunci cnd un articol trebuie introdus ntr-un tablou plin i de a-i njumti dimensiunea
atunci cnd o tergere ar face ca tabloul s devin mai puin plin dect jumtate. Aceast
strategie garanteaz c factorul de ncrcare al tabloului nu scade niciodat sub 1/2, dar, din
pcate, poate conduce la situaia n care costul amortizat al unei operaii s fie prea mare. Vom
considera urmtorul scenariu. Efectum n operaii asupra unui tablou T , unde n este o putere
a lui 2. Primele n/2 operaii sunt inserri care, conform unei analize anterioare, cost n total
(n). Dup aceast secven de inserri, num[T ] = dim[T ] = n/2. Pentru ultimele n/2 operaii,
presupunem c ele se efectueaz n urmtoarea ordine:

I, , , I, I, , , I, I, . . . ,

unde prin I am notat o inserare, iar prin o tergere. Prima inserare produce o expandare a
tabloului la dimensiunea n. Urmtoarele dou tergeri conduc la o contractare a tabloului napoi
la dimensiunea n/2. Urmtoarele dou inserri conduc la o expandare i aa mai departe. Exist
18.4. Tabele dinamice 319

Figura 18.3 Efectul unei secvene de n operaii Insereaz-Tablou asupra numrului numi de articole
din tablou, numrului dimi de locaii din tablou i potenialului i = 2 numi dimi , fiecare fiind
msurat dup operaia i. Linia subire i corespunde lui numi , linia groas i corespunde lui dimi , iar
cea punctat i corespunde lui i . Observai c, n momentul dinaintea unei expandri, potenialul a
crescut pn la numrul de articole din tablou, i, de aceea, este suficient pentru a plti pentru mutarea
articolelor n noul tablou. Apoi potenialul scade la 0, dar crete imediat la 2 atunci cnd articolul care
a produs expandarea este efectiv inserat.

(n) expandri i contractri, costul fiecreia fiind (n). Ca urmare, costul total al celor n
operaii este (n2 ), iar costul amortizat al unei operaii este (n).
Dificultatea legat de aceast strategie este evident: dup o expandare nu se efectueaz
suficiente tergeri pentru a putea plti pentru contractare. n mod analog, dup o contractare
nu se efectueaz suficiente inserri pentru a plti pentru o expandare.
Putem mbunti aceast strategie permind factorului de ncrcare s scad sub 1/2. Mai
precis, vom dubla n continuare dimensiunea tabloului atunci cnd un articol urmeaz a fi inserat
ntr-un tablou plin, dar vom njumti dimensiunea tabloului atunci cnd o tergere ar face ca
el s fie plin sub un sfert, n loc de pe jumtate plin ca nainte. Factorul de ncrcare al tabloului
este, deci, mrginit inferior de constanta 1/4. Dup o expandare, factorul de ncrcare devine
1/2. Astfel, jumtate din articolele tabloului trebuie terse nainte ca s aib loc o contractare,
deoarece contractarea intervine numai cnd factorul de ncrcare scade sub 1/4. Analog, dup
o contractare factorul de ncrcare al tabloului este de asemenea 1/2. Din acest motiv, numrul
de articole din tablou trebuie s se dubleze prin inserri pentru a urma o contractare, deoarece
contractarea intervine doar dac factorul de ncrcare devine mai mare dect 1.
Nu vom prezenta codul pentru terge-Tablou, deoarece este analog cu Insereaz-
Tablou. Totui, n analiza pe care o facem este convenabil s presupunem c dac numrul
de articole din tablou devine 0, atunci memoria alocat tabloului este eliberat. Cu alte cuvinte,
dac num[T ] = 0, atunci dim[T ] = 0.
Putem folosi acum metoda de potenial pentru a analiza costul unei secvene de n operaii
Insereaz-Tablou i terge-Tablou. ncepem prin a defini o funcie de potenial care ia
valoarea 0 imediat dup ce are loc o expandare i se mrete atunci cnd factorul de ncrcare
320 Capitolul 18 Analiza amortizat

crete la 1 sau scade la 1/4. Vom defini factorul de ncrcare al unui tablou T nevid prin (T ) =
num[T ]/dim[T ]. Deoarece pentru un tablou vid avem num[T ] = dim[T ] = 0 i (T ) = 1, vom
avea ntotdeauna num[T ] = (t) dim[T ], indiferent dac tabloul este vid sau nu. Vom folosi
urmtoarea funcie de potenial:

2 num[T ] dim[T ] dac (T ) 1/2,
(T ) = (18.5)
dim[T ]/2 num[T ] dac (T ) < 1/2.
S observm c funcia de potenial pentru un tablou vid este 0 i c potenialul nu este niciodat
negativ. Ca urmare, costul amortizat total al unei secvene de operaii relative la este o margine
superioar pentru costul real.
nainte de a trece la o analiz mai detaliat, ne oprim pentru a remarca unele proprieti
ale funciei de potenial. S observm c, dac factorul de ncrcare este 1/2, atunci potenialul
este 0. Cnd el devine 1, avem dim[T ] = num[T ], de unde (T ) = num[T ] i deci potenialul
este suficient pentru a plti pentru expandare atunci cnd este inserat un articol. Cnd factorul
de ncrcare este 1/4, avem dim[T ] = 4 num[T ], de unde rezult c (T ) = num[T ] i, deci,
potenialul este suficient pentru a plti pentru o contractare atunci cnd un articol este ters.
Figura 18.4 ilustreaz modul n care se comport potenialul pentru o secven de operaii.
Pentru a analiza o secven de n operaii Insereaz-Tablou i terge-Tablou, notm
prin ci costul real al operaiei i, prin cbi costul su amortizat relativ la , prin numi numrul
de articole memorate n tablou dup operaia i, prin dimi mrimea tabloului dup operaia i,
prin i factorul de ncrcare al tabloului dup operaia i, iar prin i potenialul dup operaia
i. Iniial, num0 = 0, dim0 = 0, 0 = 1, i 0 = 0.
ncepem cu cazul n care operaia i este Insereaz-Tablou. Dac i1 1/2, atunci analiza
este identic cu cea pentru expandarea tabloului, prezentat n seciunea 18.4.1. Indiferent dac
tabloul se expandeaz sau nu, costul amortizat cbi al operaiei este cel mult egal cu 3. Dac i1 <
1/2, tabloul nu poate fi expandat ca urmare a efecturii unei operaii, deoarece expandarea se
produce numai dac i1 = 1. Dac i i < 1/2, costul amortizat al operaiei i este
cbi = ci + i i1 = 1 + (dimi /2 numi ) (dimi1 /2 numi1 )
= 1 + (dimi /2 numi ) (dimi /2 (numi 1)) = 0.
Dac i1 < 1/2 dar i 1/2, atunci
cbi = ci + i i1 = 1 + (2 numi dimi ) (dimi1 /2 numi1 )
= 1 + (2 (2/numi1 + 1) dimi1 ) (dimi1 /2 numi1 )
3 3
= 3 numi1 dimi1 + 3 = 3 i1 dimi1 dimi1 + 3
2 2
3 3
< dimi1 dimi1 + 3 = 3.
2 2
Rezult c operaia Insereaz-Tablou are un cost amortizat mai mic sau egal cu 3.
Ne ntoarcem acum la cazul n care operaia i este terge-Tablou. n acest caz, numi =
numi1 1. Dac i1 < 1/2, trebuie s lum n considerare situaia n care are loc o contractare.
Dac aceasta are loc, atunci dimi = dimi1 i costul amortizat al operaiei este
cbi = ci + i i1 = 1 + (dimi /2 numi ) (dimi1 /2 numi1 )
= 1 + (dimi /2 numi ) (dimi /2 (numi + 1)) = 2.
18.4. Tabele dinamice 321

Figura 18.4 Efectul unei secvene de n operaii Insereaz-Tablou i terge-Tablou asupra


numrului numi de articole din tablou, numrului dimi de locaii din tablou, potenialului

2 numi dimi dac i 1/2,
i =
dimi /2 numi dac i < 1/2,
fiecare fiind msurat dup operaia i din secven. Linia subire corespunde lui numi , linia groas
corespunde lui dimi , iar linia punctat corespunde lui i . S observm c imediat nainte de expandare,
potenialul a crescut la numrul de articole din tablou i de aceea el este suficient pentru a plti pentru
mutarea tuturor articolelor n noul tablou. Analog, imediat nainte de a avea loc o contractare, potenialul
a crescut la numrul de articole din tablou.

Dac i1 < 1/2 i operaia i nu implic o contractare, atunci costul real al operaiei este
ci = numi + 1, deoarece este ters un articol i sunt mutate numi articole. Avem dimi /2 =
dimi1 /4 = numi + 1, iar costul amortizat al operaiei este
cbi = ci + i i1 = (numi + 1) + (dimi /2 numi ) (dimi1 /2 numi1 )
= (numi + 1) + ((numi + 1) numi ) ((2 numi + 2) (numi + 1)) = 1.
Cnd operaia i este terge-Tablou i i1 1/2, costul amortizat este, de asemenea, mr-
ginit superior de o constant. Analiza este propus spre rezolvare cititorului n exerciiul 18.4-3.
Recapitulnd, deoarece costul amortizat al fiecrei operaii este mrginit superior de o
constant, timpul real pentru orice secven de n operaii asupra unui tablou dinamic este O(n).

Exerciii
18.4-1 Argumentai de ce dac i1 1/2 i i 1/2, atunci costul amortizat al unei operaii
Insereaz-Tablou este 0.

18.4-2 S presupunem c dorim s implementm un tablou de dispersie dinamic, cu adresare


liber. De ce am putea considera tabloul plin dac factorul su de ncrcare atinge o valoare
strict mai mic dect 1? Descriei pe scurt cum trebuie fcut inserarea ntr-un asemenea tablou,
astfel nct valoarea ateptat a costului de amortizare pentru fiecare inserare s fie O(1). De
322 Capitolul 18 Analiza amortizat

ce valoarea ateptat a costului de amortizare nu este n mod obligatoriu O(1) pentru toate
inserrile?

18.4-3 Artai c, dac operaia i pe un tablou dinamic este terge-Tablou i i1 1/2,


atunci costul amortizat al operaiei, n raport cu funcia de potenial (18.5), este mrginit
superior de o constant.

18.4-4 S presupunem c, n loc s contractm tabloul prin njumtirea dimensiunii sale


atunci cnd factorul de ncrcare scade sub 1/4, l contractm prin mulirea dimensiunii sale cu
2/3 atunci cnd factorul de ncrcare scade sub 1/3. Folosind funcia de potenial
(T ) =| 2 num[T ] dim[T ] |,
artai c, pentru o operaie terge-Tablou, costul amortizat care folosete aceast strategie
este mrginit superior de o constant.

Probleme
18-1 Contor binar pe bii inveri
n capitolul 32 este prezentat un algoritm important, numit Transformarea Fourier Rapid (pe
scurt TFR). Primul pas al algoritmului TFR realizeaz o permutare cu inversarea biilor a
unui vector de intrare A[0..n 1], a crui lungime este n = 2k pentru un anumit k nenegativ.
Aceast permutare interschimb elementele de pe poziiile ale cror reprezentri binare sunt una
inversa celeilalte.
Putem exprima fiecare indice a ca o secven de k bii hak1 , ak2 , . . . , a0 i unde a =
Pk1 i
i=0 ai 2 . Definim

revk (hak1 , ak2 , . . . , a0 i) = ha0 , a1 . . . , ak1 i;


i, deci,
k1
X
revk (a) = aki1 2i .
i=0

De exemplu, dac n = 16 (adic k = 4), atunci revk (3) = 12, deoarece reprezentarea pe 4 bii a
lui 3 este 0011, a crei invers este 1100, care este tocmai reprezentarea pe 4 bii a lui 12.
a. Presupunnd c funcia revk necesit timpul (k), scriei un algoritm care s realizeze
permutarea pe bii inveri a unui vector de lungime n = 2k n timpul O(nk).
Putem folosi un algoritm bazat pe analiza amortizat pentru a mbunti timpul de execuie
a permutrii cu inversarea biilor. Folosim un contor cu inversarea biilor i o procedur In-
crementeaz-Cu-Inversarea-Biilor care, dat fiind o valoare a a contorului cu inversarea
biilor, produce revk (revk (a) + 1). De exemplu, pentru k = 4 i contorul cu inversarea biilor
iniializat cu 0, apelurile succesive ale procedurii Incrementeaz-Cu-Inversarea-Biilor
produc secvena:
0000, 1000, 0100, 1100, 0010, 1010, ... = 0, 8, 4, 12, 2, 10, ....
Probleme 323

b. Presupunem c pe calculatorul cu care lucrm cuvintele sunt memorate ca valori pe k bii


i c o unitate de timp este suficient pentru a executa asupra lor operaii de tipul deplasri
la stnga i la dreapta cu o valoare dat, I i SAU pe bii etc. Scriei o implementare a lui
Incrementeaz-Cu-Inversarea-Biilor care s realizeze o permutare cu inversarea
biilor asupra unui vector cu n elemente n timpul O(n).

c. S presupunem c putem efectua o deplasare la stnga sau la dreapta cu un bit ntr-o


unitate de timp. Mai este posibil s implementm o permutare cu inversarea biilor n
timpul O(n)?

18-2 Varianta dinamic a cutrii binare


Cutarea binar ntr-un vector ordonat necesit timp logaritmic, dar timpul necesitat de
inserarea unui nou element este liniar n dimensiunea vectorului. Putem mbunti timpul
pentru inserare prin memorarea mai multor vectori ordonai.
Mai precis, s presupunem c dorim s implementm Cutare i Insereaz pe o mulime
cu n elemente. Fie k = dlg(n+1)e i fie hnk1 , nk2 , . . . , n0 i reprezentarea binar a lui n. Folosim
k vectori ordonai A0 , A1 , . . . , Ak1 , unde pentru fiecare i = 0, 1, . . . , k 1 lungimea vectorului
Ai este 2i . Fiecare tablou poate fi doar P vid sau plin, dup cum ni = 1 sau ni = 0. Numrul total
k1
de elemente din cei k vectori va fi deci i=0 ni 2i = n. Dei fiecare vector n parte este ordonat,
nu exist o dependen anume ntre elementele din vectori diferii.

a. Artai cum se poate realiza operaia Cutare pentru aceast structur de date. Analizai
timpul de execuie pentru cazul cel mai defavorabil.

b. Artai cum poate fi inserat un element nou n aceast structur. Analizai timpii de
execuie pentru cazul cel mai defavorabil, precum i timpul amortizat de execuie.

c. Studiai modul n care poate fi implementat operaia tergere.

18-3 Arbori amortizai cu ponderi echilibrate


S considerm un arbore de cutare binar obinuit, care are ataat n plus, pentru fiecare nod
x, valoarea dim[x] care memoreaz numrul de chei din subarborele de rdcin x. Fie o
constant cu 1/2 < 1. Un nod x se numete -echilibrat dac

dim[st
anga[x]] dim[x] i dim[dreapta[x]] dim[x]

ntregul arbore este -echilibrat dac fiecare nod din arbore este -echilibrat. Urmtoarea
abordare amortizat pentru a pstra caracteristica de arbori cu ponderi echilibrate a fost sugerat
de G. Varghese.

a. Un arbore 1/2-echilibrat este, ntr-un anumit sens, att de echilibrat pe ct este posibil.
Fiind dat un nod x, ntr-un arbore binar de cutare oarecare, artai cum poate fi
reconstituit subarborele de rdcin x astfel nct s devin 1/2-echilibrat. Algoritmul
trebuie s se ncadreze n timpul (dim[x]) i poate folosi o memorie auxiliar de ordinul
O(dim[x]).

b. Artai c o cutare binar ntr-un arbore -echilibrat avnd n noduri poate fi realizat
n timpul O(lg n), pentru cazul cel mai defavorabil.
324 Capitolul 18 Analiza amortizat

Pentru ceea ce urmeaz n aceast problem, vom presupune c este strict mai mare dect 1/2.
Presupunem c operaiile Insereaz i tergere sunt implementate n modul uzual pentru un
arbore de cutare binar avnd n noduri, cu urmtoarea excepie: dup fiecare astfel de operaie,
dac toate nodurile din arbore nu mai sunt -echilibrate, atunci subarborele avnd rdcina n
nodul de acest tip, situat pe cel mai de sus nivel n arbore, este reconstituit astfel nct devine
1/2-echilibrat.
Vom analiza schema de reconstituire folosind metoda de potenial. Pentru un nod x oarecare
din arborele de cutare binar T , definim
(x) =| dim[st
anga[x]] dim[dreapta[x]] |
i definim potenialul lui T prin
X
(T ) = c (x),
xT :(x)2

unde c este o constant suficient de mare, care depinde de .


c. Artai c orice arbore de cutare binar are potenial nenegativ i c un arbore 1/2-
echilibrat are potenialul 0.
d. S presupunem c m uniti de potenial sunt suficiente pentru a plti reconstituirea unui
subarbore avnd m noduri. Ct de mare trebuie s fie c, n funcie de , pentru ca timpul
amortizat necesar reconstituirii unui subarbore care nu este -echilibrat s fie O(1).
e. Artai c, pentru un arbore -echilibrat avnd n noduri, inserarea i tergerea unui nod
-echilibrat necesit un timp amortizat de ordinul O(lg n).

Note bibliografice
Metoda de agregare a analizei amortizate a fost folosit de Aho, Hopcroft i Ullman [4].
Tarjan [189] trece n revist metodele de cotare i de potenial ale analizei amortizate i prezint
mai multe aplicaii. El atribuie paternitatea metodei de cotare mai multor autori, printre care
M. R. Brown, R. E. Tarjan, S. Huddleston i K. Mehlhorn. Tot el atribuie paternitatea metodei
de potenial lui D. D. Sleator. Termenul amortizat este datorat lui D. D. Sleator i lui R. E.
Tarjan.
V Structuri de date avansate
Introducere
n aceast parte relum, la un nivel mai avansat dect n partea a III-a, structurile de date
care permit operaii pe mulimi dinamice. De exemplu, dou dintre capitolele prii folosesc,
extensiv, tehnicile de analiz amortizat prezentate n capitolul 18.
Capitolul 19 prezint structura de B-arbore, care este arborele echilibrat folosit la memorarea
pe disc magnetic. Deoarece discul magnetic opereaz mult mai ncet dect memoria RAM,
performanele B-arborilor vor fi msurate nu numai prin timpul consumat cu operaiile de cutare
dinamice, ci i prin numrul de accese la disc efectuate. Pentru fiecare operaie, numrul de accese
la disc este proporional cu nlimea B-arborelui.
Capitolele 20 i 21 prezint implementri ale heap-urilor fuzionabile, care permit operaiile
Insereaz, Minimum, Extrage-Min i Reunete. Operaia Reunete permite fuzionarea a
dou heap-uri. Pe structurile de date din aceste capitole se pot executa, de asemenea, operaiile
terge i Descrete-Cheie.
Heap-urile binomiale, descrise n capitolul 20, execut fiecare dintre aceste operaii, n cazul
cel mai defavorabil, n timp O(lg n), unde n este numrul total de elemente din heap-ul de intrare
(sau n cele dou heap-uri de intrare n cazul Reunete). Se vede c operaia Reunete din
heap-ul binomial este superioar operaiei definite pentru heap-ul binar prezentat n capitolul 7,
acesta din urm efectund, n cel mai defavorabil caz, (n) uniti de timp pentru a fuziona.
Heap-urile Fibonacci din capitolul 21 sunt superioare heap-urilor binomiale, cel puin n sens
teoretic. Pentru msurarea performanelor heap-urilor Fibonacci se folosesc margini de timp
amortizate. Se va vedea c operaiile Insereaz, Minimum i Reunete consum n cazul
heap-urilor Fibonacci, timp amortizat de numai O(1), n timp ce Extrage-Min i terge
consum un timp amortizat de O(lg n). Cel mai mare avantaj al heap-urilor Fibonacci este acela
c Descrete-Cheie consum un timp amortizat de numai O(1). Operaia Descrete-Cheie
definit pentru heap-urile Fibonacci este asimptotic mai slab dect operaiile similare la diverii
algoritmi specifici de grafuri, motiv pentru care acetia o folosesc mai rar.
n sfrit, capitolul 22 prezint structuri de date pentru mulimi disjuncte. Se d un univers
de n elemente care sunt grupate n mulimi dinamice. Iniial, fiecare element este singur ntr-o
mulime. Operaia Reunete fuzioneaz dou mulimi, iar cererea Gsete-Mulime identific
mulimea care conine un anumit element la un moment dat. Reprezentnd fiecare mulime
printr-un arbore cu rdcin, vom obine operaii surprinztor de rapide: o secven de m operaii
se execut n timp O(m(m, n)), unde (m, n) este o funcie incredibil de ncet cresctoare n
ipoteza c n reprezint numrul de atomi din ntregul univers, (m, n) este cel mult 4. Analiza
amortizat care determin aceast limit de timp este pe att de complex pe ct de simpl este
structura de date. Capitolul 22 furnizeaz o limitare de timp interesant i relativ simpl.
Tematica abordat n aceast parte conine nu numai exemple de structuri de date avansate.
Printre altele, mai sunt incluse i urmtoarele:
O structur de date, inventat de van Emde Boas [194], care admite operaiile Mi-
nimum, Maximum, Insereaz, terge, Caut, Extrage-Min, Extract-Max,
Predecesor, Succesor. Acestea, n mulimea de chei {1, 2, ..., n} necesit, n cel mai
defavorabil caz, timpul (O(lg lg n)).
Arbori dinamici, definii de ctre Sleator i Tarjan [177] i apoi reluai de Tarjan [188].
Cu ajutorul lor se ntreine o pdure de arbori cu rdcini disjuncte. Fiecare arc din fiecare
Introducere 327

arbore are ataat, drept cost, un numr real. n arborii dinamici se pot efectua operaiin
vederea aflrii prinilor, rdcinilor, costurilor arcelor, costului minim al unui drum de la
un nod la o rdcin. Arborii pot fi manevrai prin tierea de arce, modificarea costurilor
arcelor de pe un drum de la un nod la o rdcin, legarea unei rdcini la un alt arbore
etc. Una dintre implementrile arborilor dinamici necesit un timp amortizat de O(lg n)
pentru fiecare operaie. O alt implementare, mai sofisticat, necesit timp O(lg n) n cel
mai defavorabil caz.
Arborii splay (Oblici), dezvoltai de ctre Sleator i Tarjan [178] i apoi reluai de
Tarjan [188], sunt un tip de arbori binari de cutare care dau un timp amortizat O(lg n)
pentru toate operaiile standard. Una dintre aplicaiile acestor arbori permite simplificarea
arborilor dinamici.
Structurile de date persistente permit att cereri, ct i, uneori, actualizri ale versiunilor
vechi ale structurii. Sunt prezentate tehnicile de creare a structurilor de date nlnuite
persistente descrise de ctre Driscoll, Sarnak, Sleator i Tarjan n [59]. Acestea sunt eficiente
deoarece consum foarte puin timp i spaiu. Problema 14-1 d un exemplu simplu de
mulime (de arbori) dinamic persistent.
19 B-arbori

Un B-arbore este un arbore echilibrat, destinat cutrii de informaii memorate pe disc


magnetic sau pe alt tip de suport adresabil direct. B-arborii sunt similari cu arborii rou-negru
(capitolul 14), dar ei minimizeaz operaiile de intrare/ieire disc.
Diferena esenial fa de arborii rou-negru este aceea c fiecare nod dintr-un B-arbore poate
avea un numr mare de fii, pn la ordinul miilor. Astfel, factorul de ramificare poate fi foarte
mare i este, de regul, determinat doar de caracteristicile unitii de disc utilizate. Similaritatea
cu arborii rou-negru const n faptul c ambii au nlimea O(lg n), unde n este numrul de
noduri, dei nlimea unui B-arbore poate fi considerabil mai mic din cauza factorului de
ramificare mult mai mare. Din aceast cauz, B-arborii, pot fi, de asemenea, folosii pentru a
implementa n timp O(lg n) diverse operaii pe mulimi dinamice.
B-arborii sunt o generalizare natural a arborilor binari, dup cum se poate vedea i din
figura 19.1 n care este ilustrat un B-arbore. Dac un nod x al unui B-arbore conine n[x] chei,
atunci x are n[x] + 1 fii. Cheile nodului x sunt folosite pentru a separa domeniul de chei vizibile
din x n n[x]+1 subdomenii, fiecare dintre acestea fiind vizibile prin unul dintre fiii lui x. Cnd se
caut o cheie ntr-un B-arbore, exist n[x] + 1 posibiliti de parcurgere, n funcie de rezultatul
comparrii cu cele n[x] chei memorate n nodul x.
n seciunea 19.1 se d definiia exact a B-arborelui i se demonstreaz c nlimea lui
crete logaritmic cu numrul de noduri. Seciunea 19.2 descrie cutarea i inserarea ntr-un B-
arbore, iar seciunea 19.3 prezint tergerea. nainte de acestea, vom discuta despre structurile
de date, proiectate s lucreze pe disc magnetic i vom evidenia diferenele de proiectare fa de
structurile de acces din memoria intern.

Structuri de date n memoria secundar


Exist o mulime de tehnologii dezvoltate pentru a permite exploatarea eficient a memoriei
unui sistem de calcul. Memoria intern (memoria principal) a unui sistem este compus
din chip-uri de memorie din silicon, fiecare dintre ele putnd s pstreze circa un milion de bii de
informaie. Costul acestei tehnologii este mai scump per bit de informaie dect costul similar al
tehnologiei magnetice: discuri sau benzi. Din aceast cauz sistemele de calcul au i o memorie
secundar, rezident de obicei pe disc magnetic. Capacitatea acestui tip de suport depete

Figura 19.1 Un B-arbore n care cheile sunt consoane ale alfabetului latin. Un nod intern x conine
n[x] chei i are n[x]+1 fii. Toate frunzele sunt pe acelai nivel n arbore. Nodurile haurate deschis indic
traseul de cutare a literei R.
Capitolul 19 B-arbori 329

Figura 19.2 Schema unei uniti de disc

cu cteva ordine de mrime capacitatea memoriei principale.


n figura 19.2 este prezentat, schematic, o unitate de disc magnetic clasic. Suprafaa discului
este acoperit cu o pelicul de material magnetizabil. Capul de citire/scriere poate citi/scrie de
pe/pe aceast suprafa n timpul rotaiei acesteia. Braul de citire/scriere poate poziiona capul
la diferite distane de centrul discului. Atunci cnd braul staioneaz, partea din suprafa,
care trece n timpul rotaiei prin faa unui cap de citire/scriere poart numele de pist. Adesea,
informaiile nmagazinate pe o pist sunt mprite ntr-un numr fixat de buci de lungime
egal, numite pagini ; de obicei pagina unui disc are lungimea de 2048 octei. Pagina este unitatea
de baz a schimbului dintre disc i memoria intern. Timpul de acces la o pagin const din
timpul necesar poziionrii capului pe pist, urmat de ateptarea trecerii paginii prin faa capului.
Acest timp (de exemplu 20ms) este mult mai mare dect timpul necesar citirii/scrierii respective,
deoarece poziionarea este o activitate mecanic, pe cnd citirea/scrierea este una electronic.
Din aceast cauz, o dat ce poziionarea este corect, citirea/scrierea unei mari cantiti de
informaie de pe pista respectiv se face foarte rapid.
De regul, timpul de citire a unei pagini este mai mare dect timpul necesar examinrii i
prelucrrii complete a informaiilor citite. De aceea, n aceast seciune vom analiza separat cele
dou componente ale timpului de execuie:

numrul de accese la disc;

timpul de calcul al CPU.

Numrul de accese la disc va fi exprimat n funcie de numrul de pagini citite sau scrise pe
disc. Trebuie reinut c accesul la disc nu este constant, ci depinde de distana dintre poziia
curent i pista int, ca i de starea curent a micrii de rotaie. Pentru a simplifica lucrurile,
vom aproxima numrul de pagini citite prin numrul de accese la disc.
ntr-o aplicaie clasic de B-arbori, cantitatea de informaie manipulat depete cu mult
capacitatea memoriei interne. Algoritmii specifici B-arborilor copiaz, de pe disc n memorie,
acele pagini de care este strict nevoie i le scriu napoi pe cele care au fost modificate. Aceti
algoritmi presupun prezena simultan n memorie a unui numr constant de pagini, motiv
pentru care dimensiunea memoriei principale nu limiteaz dimensiunile B-arborilor care sunt
manevrai.
330 Capitolul 19 B-arbori

n continuare, vom descrie, n pseudocod schema cadru de utilizare a discului. Fie x un


pointer la un obiect. Dac obiectul se afl n memoria intern, atunci ne vom referi la el n mod
obinuit: cheie[x]. Dac obiectul este momentan pe disc, atunci, mai nti, trebuie s efectum
operaia Citete-Disc(x) pentru aducerea lui x n memoria intern nainte de a-i putea referi
cmpurile. Dac x este n memorie, atunci el nu mai trebuie citit. n mod analog, vom folosi
operaia Scrie-Disc(x) dac s-au efectuat modificri asupra componentelor lui x, pentru a le
salva. Astfel, scenariul clasic de prelucrare a unui obiect este:
1: ...
2: x un pointer la un obiect
3: Citete-Disc(x)
4: operaii de acces i/sau de modificare a cmpurilor lui x
5: Scrie-Disc(x) se omite dac x nu s-a modificat
6: alte operaii de acces care nu modific cmpul lui x
7: ...

n fiecare moment, sistemul poate pstra n memoria intern numai un numr limitat de
pagini. Algoritmii specifici B-arborilor presupun c exist suficient spaiu n memoria intern n
acest scop.
Pe cele mai multe sisteme, timpii de execuie ai algoritmilor de B-arbori sunt extrem de
sensibili la numrul de operaii Citete-Disc i Scrie-Disc. Din acest motiv ar fi normal ca
un nod n B-arbore s aib lungimea unei pagini disc. De asemenea, numrul de fii ai unui nod
este bine s fie ct mai mare.
De obicei, factorul de ramificare este ntre 50 i 2000, n funcie de lungimea cheii i de
lungimea unei pagini. Un factor de ramificare mare reduce drastic nlimea arborelui i numrul
de accese la disc pentru accesul la o cheie. De exemplu, n figura 19.3 este prezentat un B-arbore
cu factorul de ramificare 1001 i nlimea 2, care permite memorarea unui miliard de chei. Cu
toate acestea, deoarece nodul rdcin poate fi pstrat permanent n memorie, sunt necesare
numai dou accese la disc pentru a gsi orice cheie din acest arbore.

19.1. Definiia B-arborelui


Pentru a simplifica lucrurile, vom presupune, ca i la arborii binari i la cei rou-negru, c
informaia adiional asociat unei chei este memorat n acelai loc cu cheia. n practic,
fiecrei chei i este ataat un pointer care repereaz informaia adiional ataat cheii. De
asemenea, la B-arbori se obinuiete, tocmai pentru a crete factorul de ramificare, ca, n nodurile
interne s se memoreze numai chei i pointeri spre fii, iar informaia adiional (pointer la ea)
s fie nregistrat doar n frunze.
Un B-arbore T este un arbore cu rdcin (cu rdcina r adacin
a[T ]) care are urmtoarele
proprieti:
1. Fiecare nod x are urmtoarele cmpuri:
a. n[x], numrul curent de chei memorate n x,
b. cele n[x] chei, memorate n ordine nedescresctoare cheie1 [x] cheie2 [x] . . .
cheien[x] [x] i
19.1. Definiia B-arborelui 331

Figura 19.3 Un B-arbore de nlime 2 conine peste un miliard de chei. Fiecare nod intern sau frunz
conine 1000 de chei. Exist 1001 noduri pe nivelul 1 i peste un milion de frunze pe nivelul 2. Numrul
scris n interiorul fiecrui nod x indic numrul n[x] de chei din x.

c. valoarea boolean f runz


a[x], care este adevrat dac nodul x este frunz i fals
dac nodul este intern.

2. Dac x este un nod intern, el mai conine n[x] + 1 pointeri spre fiii lui c1 [x], c2 [x], . . .,
cn[x]+1 [x]. Nodurile frunz nu au fii, astfel cmpurile lor ci sunt nedefinite.

3. Cheile cheiei [x] separ domeniile de chei aflate n fiecare subarbore: dac ki este o cheie
oarecare memorat ntr-un subarbore cu rdcina ci [x], atunci

k1 cheie1 [x] k2 cheie2 [x] . . . cheien[x] [x] kn[x]+1 .

4. Fiecare frunz se afl la aceeai adncime, care este nlimea h a arborelui.

5. Exist o limitare inferioar i una superioar a numrului de chei ce pot fi coninute ntr-un
nod. Aceste margini pot fi exprimate printr-un ntreg fixat t 2, numit grad minim al
B-arborelui:

a. Fiecare nod, cu excepia rdcinii, trebuie s aib cel puin t 1 chei i n consecin
fiecare nod intern, cu excepia rdcinii, trebuie s aib cel puin t fii. Dac arborele
este nevid, atunci rdcina trebuie s aib cel puin o cheie.
b. Fiecare nod poate s conin cel mult 2t 1 chei. De aceea, orice nod intern poate
avea cel mult 2t fii. Un nod cu 2t 1 chei se va numi nod plin.

Cel mai simplu B-arbore apare cnd t = 2. Orice nod intern poate avea 2, 3 sau 4 fii, motiv
pentru care i se mai spune 2-3-4 arbore. Cu toate acestea, n practic, se folosesc valori mult
mai mari pentru t.

nlimea unui B-arbore


Numrul de accese la disc cerute de cele mai multe operaii n B-arbore este proporional cu
nlimea B-arborelui. Vom analiza acum cazul cel mai defavorabil pentru nlime.
332 Capitolul 19 B-arbori

Teorema 19.1 Dac n 1, atunci, pentru orice B-arbore T cu n chei de nlime h i gradul
mimim t 2,
n+1
h logt .
2
Demonstraie. Dac un B-arbore are nlimea h, va avea numr minim de chei dac rdcina
conine doar o cheie i toate celelalte noduri cte t 1 chei. n acest caz, exist dou noduri
pe nivelul 1, 2t noduri pe nivelul 2, 2t2 noduri pe nivelul 3 .a.m.d, 2th1 noduri pe nivelul h.
Figura 19.4 prezint un astfel de arbore pentru h = 3. De aceea, numrul n al cheilor satisface
inegalitatea
h
X
th 1
n 1 + (t 1) 2ti1 = 1 + 2(t 1) = 2th 1,
i=1
t1

ceea ce demonstreaz teorema.

Figura 19.4 Un B-arbore de nlime 3 care conine numrul minim posibil de chei. n fiecare nod x
este scris numrul efectiv de chei din nod, n[x].

Aici se vede puterea B-arborilor n comparaie cu arborii rou-negru. Dei nlimea ambilor
crete proporional cu O(lg n), t fiind o constant, baza logaritmului la B-arbore poate fi, de
multe ori, mai mare. De aceea, numrul nodurilor examinate la B-arbori scade cu factorul lg t
fa de arborii rou-negru pentru majoritatea operaiilor asupra arborilor. Astfel, numrul de
accese la disc pentru B-arbori se reduce, automat, cu acest factor.

Exerciii
19.1-1 De ce nu se permite gradul minim t = 1?

19.1-2 Pentru ce valori ale lui t, arborele din figura 19.1 este un B-arbore n conformitate cu
definiia?

19.1-3 Ilustrai toi B-arborii coreci cu gradul minim 2 care reprezint mulimea {1, 2, 3, 4, 5}.
19.2. Operaii de baz n B-arbore 333

19.1-4 Determinai, n funcie de gradul minim t, o margine superioar minim a numrului de


chei care pot fi memorate ntr-un B-arbore de nlime h.

19.1-5 Descriei structura de date care rezult cnd fiecare nod negru dintr-un arbore rou-
negru absoarbe fiul lui rou, ncorpornd fiii lui cu el nsui.

19.2. Operaii de baz n B-arbore


n aceast seciune, vom prezenta n detaliu, operaiile Caut-B-Arbore, Creeaz-B-Ar-
bore i Inereaz-B-Arbore. Pentru aceste proceduri facem urmtoarele convenii:

Rdcina B-arborelui se afl ntotdeauna n memoria intern, astfel c, pentru ,ea nu este
necesar operaia Citete-Disc. Operaia Scrie-Disc se impune, totui, atunci cnd se
modific rdcina.

Fiecare nod transmis ca parametru trebuie s fi fost citit cu ajutorul procedurii Citete-
Disc.

Procedurile prezentate sunt toate dintr-o singur trecere, arborele fiind parcurs de la rd-
cin spre frunze, fr reveniri.

Cutarea n B-arbore
Cutarea ntr-un B-arbore este analog cu cutarea ntr-un arbore binar. Evident, n locul
unei decizii binare care indic una dintre cele dou ci posibile, aici vom avea de-a face cu o
ramificare multipl spre nodurile fii. Mai exact, la fiecare nod intern x, se ia o decizie din n[x] + 1
alternative.
Caut-B-Arbore este o generalizare natural a procedurii Caut-Arbore definit pentru
arborii binari. Caut-B-Arbore primete la intrare un pointer la nodul rdcin x i o cheie
k ce trebuie cutat n subarborele de rdcin x. La cel mai de sus nivel se va apela sub
forma: Caut-B-Arbore(r adacin
a[T ], k). Dac k este n B-arbore, atunci Caut-B-Arbore
returneaz perechea ordonat (y, i) reprezentnd un nod y i un indice i, astfel nct cheiei [y] = k.
n caz contrar, returneaz valoarea nil.
Folosind o procedur de cutare liniar, liniile 13 gsesc cel mai mic i pentru care
k cheiei [x] dau lui i valoarea n[x] + 1 n caz contrar. Liniile 45 verific dac cheia a fost
descoperit i, n caz afirmativ, returneaz valoarea corespunztoare. Liniile 610 ori termin
operaia cu insucces (dac x este o frunz), ori reapeleaz recursiv cutarea acestui fiu n
subarborele corespunztor, dup citirea prealabil a acestuia.
n figura 19.1 se ilustreaz operaia de cutare Caut-B-Arbore a cheii R ntr-un B-arbore.
Sunt evideniate nodurile vizitate n acest caz.
La fel ca la procedura Caut-Arbore definit pentru arbori binari, n timpul apelurilor
recursive, sunt parcurse nodurile pe o cale de la rdcin n jos. Din aceast cauz, numrul
paginilor disc accesate de Caut-B-Arbore sunt (h) = (logt n), unde h este nlimea B-
arborelui, i n numrul de chei. Deoarece n[x] < 2t, timpul consumat n ciclul ct timp din
liniile 23, pentru fiecare nod, este O(t) i timpul total CPU este O(th) = O(t logt n).
334 Capitolul 19 B-arbori

Crearea unui B-arbore vid


Pentru a construi un B-arbore T , mai nti, se aplic procedura Creeaz-B-Arbore pentru
a crea un nod rdcin vid. Apoi, se apeleaz procedura Inereaz-B-Arbore pentru a aduga
cte o cheie nou. Fiecare dintre aceste dou proceduri folosete o procedur auxiliar Aloc-
Nod, care, n timp O(1), aloc o pagin disc spre a fi folosit drept nod nou. Presupunem c
nodul creat prin Aloc-Nod nu necesit Citete-Disc deoarece pentru crearea unui nod nou
nu sunt necesare informaii de pe disc. Operaia Creeaz-B-Arbore necesit O(1) accesri de
disc i O(1) timp CPU.

Caut-B-Arbore(x, k)
1: i 1
2: ct timp i n[x] i k > cheiei [x] execut
3: ii+1
4: dac i n[x] i k = cheiei [x] atunci
5: returneaz (x, i)
6: dac f runz
a[x] atunci
7: returneaz nil
8: altfel
9: Citete-Disc(ci [x])
10: returneaz Caut-B-Arbore(ci [x], k)

Creeaz-B-Arbore(T )
1: x Aloc-Nod()
2: f runza[x] adevrat
3: n[x] 0
4: Scrie-Disc(x)
5: r
adacina[T ] x

Divizarea unui nod


Inserarea ntr-un B-arbore este, n mod esenial, mai complicat dect inserarea unei chei ntr-
un arbore binar de cutare. Una dintre operaiile fundamentale folosite n timpul inserrii este
divizarea unui nod plin y (care are 2t1 chei) n dou noduri n jurul cheii mediane cheiet [y],
avnd cte t 1 chei fiecare. Cheia median se deplaseaz la locul potrivit n nodul printe (care
nainte de deplasare nu trebuie s fie plin) spre a repera fiecare dintre cei doi subarbori obinui
prin divizarea lui y. Dac nodul y nu are printe, atunci nlimea B-arborelui crete cu unu.
Deci divizarea este cea care provoac creterea nlimii.
Procedura Divide-Fiu-B-Arbore primete ca intrare un nod intern x care nu este plin
(presupus a fi n memoria principal), un indice i i un nod y astfel nct y = ci [x] este un fiu
plin al lui x. Procedura divide nodul y n dou i rearanjeaz x astfel nct acesta va avea nc
un fiu.
Figura 19.5 ilustreaz acest proces. Nodul plin y este divizat dup cheia lui median S care
este mutat n nodul printe x. Cheile mai mari dect S din y sunt mutate ntr-un nod nou z
care devine un nou fiu al lui x.
19.2. Operaii de baz n B-arbore 335

Figura 19.5 Divizarea unui nod cu t = 4. Nodul y este divizat n dou noduri y i z, iar cheia median
S este mutat n printele lui y.

Divide-Fiu-B-Arbore(x, i, y)
1: z Aloc-Nod()
2: f runz a[z] f runz a[y]
3: n[z] t 1
4: pentru j 1, t 1 execut
5: cheiej [z] cheiej+t [y]
6: dac nu f runz a[y] atunci
7: pentru j 1, t execut
8: cj [z] cj+t [y]
9: n[y] t 1
10: pentru j n[x] + 1, i + 1, 1 execut
11: cj+1 [x] cj [x]
12: ci+1 [x] z
13: pentru j n[x], i, 1 execut
14: cheiej+1 [x] cheiej [x]
15: cheiei [x] cheiet [y]
16: n[x] n[x] + 1
17: Scrie-Disc(y)
18: Scrie-Disc(z)
19: Scrie-Disc(x)

Procedura Divide-Fiu-B-Arbore lucreaz ntr-o manier obinuit cut and paste. Astfel
y, al i-lea fiu al lui x, este nodul care va fi divizat. Nodul y are iniial 2t 1 fii, dar dup divizare
i mai rmn doar primii t 1 fii. Nodul z adopt ultimii t 1 fii ai lui y, n timp ce cheia
median este deplasat n printele x, spre a separa nodurile y i z.
Liniile 18 creeaz nodul z, deplaseaz ultimele t 1 chei i cei t subarbori corespunztori
din nodul y. Linia 9 actualizeaz numrul de chei din y. Liniile 1016 insereaz z ca fiu al lui
x, mut cheia median din y n x spre a separa nodurile y i z i actualizeaz numrul de chei
din x. n sfrit, liniile 1719 cer scrierea paginilor disc modificate. Timpul CPU consumat de
Divide-Fiu-B-Arbore este (t) datorit ciclurilor din liniile 45 i 78 (celelalte cicluri au cel
mult t iteraii).
336 Capitolul 19 B-arbori

Figura 19.6 Divizarea rdcinii cu t = 4. Nodul rdcin r este divizat n dou i se creeaz un nou
nod rdcin s. Noul nod conine cheia median din r i ca fii cele dou jumti ale lui r. nlimea
B-arborelui crete cu 1 cnd rdcina este divizat.

Inserarea unei chei ntr-un B-arbore


Operaia de inserare a unei chei k ntr-un B-arbore de nlime h se execut ntr-o singur
parcurgere, cobornd n arbore, i cere O(h) accese disc. Timpul CPU cerut este O(th) =
O(t logt n). Procedura Insereaz-B-Arbore folosete procedura Divide-Fiu-B-Arbore spre
a se asigura c nici un descendent nu va deveni nod plin.

Insereaz-B-Arbore(T, k)
1: r r ad
acin a[T ]
2: dac n[r] = 2t 1 atunci
3: s Aloc-Nod()
4: r
ad acina[T ] s
5: f runz a[s] fals
6: n[s] 0
7: c1 [s] r
8: Divide-Fiu-B-Arbore(s, 1, r)
9: Insereaz-B-Arbore-Neplin(s, k)
10: altfel
11: Insereaz-B-Arbore-Neplin(r, k)

Liniile 39 trateaz cazul n care nodul rdcin r este plin: se creeaz o rdcin nou s
cu doi descendeni i este divizat vechea rdcin r. Divizarea rdcinii este singura operaie
care determin creterea nlimii B-arborelui. n figura 19.6 este ilustrat aceast situaie. Spre
deosebire de arborii binari, care cresc n jos (spre frunze), B-arborele crete n partea de sus,
prelungind rdcina. Procedura se ncheie apelnd Insereaz-B-Arbore-Neplin pentru a
insera cheia k ntr-un arbore cu o rdcin care nu este plin. Aceast din urm procedur
parcurge arborele recursiv spre frunze, garantndu-se faptul c, dup parcurgere, nu vor rmne
noduri pline (dac este cazul se va apela Divide-Fiu-B-Arbore.
Procedura recursiv auxiliar Insereaz-B-Arbore-Neplin insereaz cheia k n nodul x
despre care se presupune c nu este plin la momentul apelului. mpreun cu Insereaz-B-
Arbore, se asigur aceast condiie pentru toate nodurile parcurse.
19.2. Operaii de baz n B-arbore 337

Insereaz-B-Arbore-Neplin(x, k)
1: i n[x]
2: dac f runz a[x] atunci
3: ct timp i 1 i k < cheiei [x] execut
4: cheiei+1 [x] cheiei [x]
5: ii1
6: cheiei+1 [x] k
7: n[x] n[x] + 1
8: Scrie-Disc(x)
9: altfel
10: ct timp i 1 i k < cheiei [x] execut
11: ii1
12: ii+1
13: Citete-Disc(ci [x])
14: dac n[ci [x]] = 2t 1 atunci
15: Divide-Fiu-B-Arbore(x, i, ci [x])
16: dac k > cheiei [x] atunci
17: ii+1
18: Insereaz-B-Arbore-Neplin(ci [x], k)

Procedura Insereaz-B-Arbore-Neplin lucreaz dup cum urmeaz. Liniile 38 insereaz


k n x cnd x este un nod frunz. Dac x nu este frunz, atunci k trebuie inserat n frunza
potrivit, ntr-un subarbore al lui x. n acest caz, liniile 912, determin fiul lui x de la care
trebuie mers descendent. Linia 14 detecteaz dac apare un nod plin, caz n care linia 15 apeleaz
divizarea, iar n liniile 1617 se alege nodul pe care se coboar n arbore, dintre cei doi fii obinui
prin divizare. Trebuie remarcat c, dup incrementarea lui i din linia 17, nu mai trebuie apelat
Citete-Disc(ci [x]) deoarece apelul recursiv asigur c fiul este deja citit n urma crerii lui
prin Divide-Fiu-B-Arbore. Ca urmare a aciunii liniilor 1417, se garanteaz c nu vor mai
aprea noduri pline. Linia 18 intr n recursivitate pentru a insera k n subarborele potrivit. n
figura 19.7 se ilustreaz cteva dintre cazurile care pot s apar la inserarea n B-arbore.
Numrul de accesri de disc efectuate de Insereaz-B-Arbore este O(h), unde h este
nlimea B-arborelui, deoarece ntre apelurile Insereaz-B-Arbore-Neplin sunt efectuate
numai O(1) accese la disc. Timpul total CPU este O(th) = O(t logt n). Deoarece Insereaz-
B-Arbore-Neplin folosete recursivitatea de coad,ea poate fi transformat ntr-un ciclu ct
timp, ceea ce arat c, n fiecare moment, numrul de pagini din memoria intern este O(1).

Exerciii
19.2-1 Artai rezultatul inserrii cheilor F, S, Q, K, C, L, H, T, V, W, M, R, N, P, A, B, X, Y,
D, Z, E, n aceast ordine, ntr-un B-arbore, iniial vid. Desenai configuraiile din arbore care
preced divizri de noduri i desenai configuraia final.

19.2-2 Explicai n ce condiii pot fi (sunt) executate operaii redundante de acces la disc la
apelarea procedurii Insereaz-B-Arbore. (O operaie Citete-Disc este redundant dac
pagina este deja n memorie, iar o operaie Scrie-Disc este redundant dac informaia scris
din memorie este identic cu cea de pe disc.)
338 Capitolul 19 B-arbori

Figura 19.7 Inserarea de chei ntr-un B-arbore. Acesta are gradul minim t = 3, deci un nod poate avea
cel mult 5 chei. Nodurile modificate prin inserri sunt haurate mai deschis. (a) Arborele iniial. (b)
Rezultatul inserrii cheii B introducerea ei n frunz. (c) Introducerea cheii Q n arborele precedent:
nodul RST U V este divizat n dou noduri coninnd RS i U V , cheia T este mutat n rdcin, iar
Q este inserat n partea stng a nodului RS. (d) Rezultatul inserrii cheii L n arborele precedent.
Rdcina este divizat, iar nlimea B-arborelui crete cu 1. Apoi L este inserat n frunza care conine
JK. (e) Rezultatul inserrii cheii F n arborele anterior. Nodul ABCDE este divizat nainte ca F s
fie inserat n nodul DE.

19.2-3 Explicai cum se poate gsi cheia minim memorat ntr-un B-arbore i cum se poate
gsi predecesorul unei chei memorate ntr-un B-arbore.

19.2-4 ? Presupunem c cheile {1, 2, . . . , n} sunt inserate ntr-un B-arbore iniial vid cu gradul
minim 2. Cte noduri va avea n final acest B-arbore?

19.2-5 Deoarece nodurile frunz nu conin pointeri la subarbori fii, se poate concepe folosirea
n frunze a unei valori t diferite (mai mari) dect la nodurile interne pentru a ocupa mai eficient
19.3. tergerea unei chei dintr-un B-arbore 339

paginile disc. Artai cum se modific procedurile de creare i inserare ntr-un B-arbore n acest
caz.

19.2-6 Presupunem c algoritmul Caut-B-Arbore este implementat folosind, n interiorul


nodurilor, cutarea binar n locul celei liniare. Artai c, prin aceasta, timpul CPU este O(lg n),
independent de t ca funcie de n.

19.2-7 Presupunem c echipamentul disc permite s se aleag arbitrar lungimea paginii, dar c
timpul de citire a unei pagini, cu o lungime selectat, este a + bt, unde a i b sunt constante date,
iar t este gradul minim al B-arborelui. Descriei cum trebuie ales t, astfel nct s minimizeze
(aproximativ) timpul de cutare n B-arbore. Cutai, de exemplu, o valoare optim pentru t n
cazul a = 30 milisecunde i b = 40 microsecunde.

19.3. tergerea unei chei dintr-un B-arbore


Operaia de tergere dintr-un B-arbore este analog celei de inserare, ns este puin mai
complicat. n loc s descriem complet algoritmii necesari, vom schia doar modul de lucru.
Presupunem c procedurii terge-B-Arbore i se cere s tearg cheia k din subarborele de
rdcin x. Procedura trebuie s asigure (recursiv) faptul c numrul de chei din x este cel puin
t. Aceast cerin apare din faptul c, n urma unei tergeri, se diminueaz cu 1 numrul cheilor
dintr-un nod, deci este posibil s nu mai poat avea t chei n el. n acest caz, poate avea loc
un proces de fuziune (invers divizrii), caz n care o cheie coboar ntr-un fiu nainte de a i se
aplica acestuia (recursiv) procedura de tergere. Dac ntr-un astfel de proces rdcina rmne
fr nici o cheie, deci cu un singur fiu, atunci se terge rdcina veche, iar unicul fiu devine
noua rdcin a arborelui, scznd nlimea arborelui cu 1 i pstrnd proprietatea arborelui
cel puin o cheie (doar dac arborele nu este vid).
Figura 19.8 ilustreaz cteva cazuri de tergere de chei dintr-un B-arbore.

1. Dac cheia k este ntr-un nod x care este frunz, atunci se terge cheia k din nodul x.

2. Dac cheia k este n nodul interior x, atunci:

a. Dac fiul y care precede cheia k are cel puin t chei, atunci se caut predecesorul k 0 al
cheii k n subarborele de rdcin y. Se terge k 0 i se nlocuiete k din x cu k 0 , dup
care se aplic mai departe, recursiv, aceeai regul. (Gsirea cheii k 0 i tergerea ei se
poate face ntr-un singur pas.)
b. n manier simetric, dac fiul z care succede cheia k n nodul x are cel puin t chei,
atunci se caut succesorul k 0 al cheii k n subarborele de rdcin z. Se terge k 0 i
se nlocuiete k din x cu k 0 , dup care se aplic mai departe, recursiv, aceeai regul.
(Gsirea cheii k 0 i tergerea ei se poate face ntr-un singur pas.)
c. n caz contrar, dac att y ct i z au numai cte t1 chei, cele dou noduri fuzioneaz
n sensul c n y intr k i toate cheile din z, dup care y va conine 2t 1 chei. Apoi
se elibereaz nodul z i recursiv, se terge cheia k din y.
340 Capitolul 19 B-arbori

Figura 19.8 tergerea de chei dintr-un B-arbore. Gradul lui minim este t = 3 astfel c nodurile, cu
excepia rdcinii, nu pot avea mai puin de 2 chei. Nodurile modificate sunt haurate mai deschis.
(a) B-arborele din figura 19.7(e). (b) tergerea cheii F corespunde cazului 1: tergere din frunz. (c)
tergerea cheii M : cazul 2a, cheia L care l precede pe M este mutat n vechiul loc al lui M . (d)
tergerea cheii G: cazul 2c, cheia G este pus mai jos i se formeaz prin fuziune nodul DEGJK, dup
care G este ters din frunz (cazul 1). (e) tergerea cheii D: cazul 3b, recurena nu poate s coboare
din nodul CL deoarece are numai dou chei, deci P este mpins n jos i prin fuzionarea cu CL i T X
se obine nodul CLP T X; apoi se terge D din frunz (cazul 1). (e) Dup (d) se terge rdcina i
nlimea scade cu 1. (f ) tergerea cheii B: cazul 3a, C este mutat n vechiul loc al lui B i E este mutat
n locul lui C.

3. Dac cheia k nu este prezent n nodul intern x, se determin rdcina ci [x] care indic
subarborele n care se afl cheia k, dac aceasta se afl n arbore. Dac ci [x] are numai
t 1 chei, se execut paii 3a sau 3b, necesari pentru a se pstra n noduri numrul minim
de t chei. Apoi se reaplic recursiv procedura la fiul potrivit al lui x.

a. Dac ci [x] are numai t 1 chei, dar are un nod frate n stnga sau n dreapta lui care
Probleme 341

are t chei, are loc mutarea unei chei din x n ci [x], apoi mutarea unei chei n x din
fratele din stnga sau dreapta a lui ci [x].
b. Dac ci [x] i fraii lui au cte t 1 chei, fuzioneaz ci cu unul dintre frai, ceea ce
implic mutarea unei chei din x n nodul nou fuzionat ca i cheie median.

Deoarece majoritatea cheilor dintr-un B-arbore sunt n frunze, ne ateptm ca, n practic,
cele mai multe tergeri s aib loc n frunze. Procedura de tergere terge-B-Arbore
acioneaz descendent i fr reveniri. Cnd se terge o cheie dintr-un nod intern, au loc o
serie de nlocuiri de chei, astfel nct tergerea efectiv s se fac n frunz (cazurile 2a sau 2b).
Dei procedura pare complicat, ea presupune numai O(h) accese la disc pentru un B-arbore
de nlime h, deoarece ntre dou apeluri recursive au loc numai O(1) accese la disc. Timpul
CPU necesar este de O(th) = O(t logt n).

Exerciii
19.3-1 Prezentai rezultatele obinute dup tergerea, n aceast ordine, a cheilor C, P i V din
B-arborele din figura 19.8(f).

19.3-2 Descriei, n pseudocod, procedura terge-B-Arbore.

Probleme
19-1 Stive n memoria secundar
Considerm implementarea unei stive pentru un sistem de calcul care are o memorie intern
rapid relativ mic i o memorie secundar pe disc lent, dar practic orict de mare. Operaiile
specifice Pune-n-Stiv i Scoate-Din-Stiv au ca operand un cuvnt. Se admite creterea
orict de mare a acestei stive; ceea ce depete memoria intern, se extinde automat pe disc.
342 Capitolul 19 B-arbori

O implementare simpl, dar ineficient, pstreaz ntreaga stiv pe disc. n memorie se


pstreaz doar un pointer la stiv, care este adresa elementului din vrful stivei. Dac p este
valoarea acestui pointer, m este numrul de cuvinte dintr-o pagin, atunci bp/mc este numrul
paginii de pe disc, iar primul element este al p mod m-lea cuvnt din pagin.
Pentru implementarea procedurii Pune-n-Stiv, se incrementeaz pointerul de stiv, se
citete pagina disc corespunztoare, se copiaz coninutul cuvntului n vrful paginii din
vrful stivei, dup care pagina se rescrie pe disc. Operaia Scoate-Din-Stiv este similar:
se decrementeaz pointerul de stiv, se citete pagina corespunztoare, se extrage elementul din
vrful stivei dup care pagina se rescrie pe disc.
Deoarece operaiile cu discul sunt relativ costisitoare, vom folosi numrul de operaii disc ca
msur a eficienei. Vom contoriza timpul CPU i vom cere (m) pentru fiecare acces disc la o
pagin de m cuvinte.

a. Care este valoarea asimptotic a numrului de accese disc la o stiv cu n operaii asupra
stivei, n cel mai defavorabil caz? Care este timpul CPU pentru n operaii pe stiv?
(Rspunsul se va exprima n funcie de m i n).

S considerm o implementare n care se pstreaz permanent n memoria intern o pagin


a stivei. (Evident, vom ti copia crei pagini disc se afl n memorie). Se pot face operaii asupra
stivei numai dac pagina respectiv se afl n memorie. Dac este cazul, pagina curent de pe
disc se rescrie i se recitete alta. Dac pagina este deja n memorie, nu se mai acceseaz discul
pentru ea.

b. Care este, n cel mai defavorabil caz, numrul de accese la disc i timpul CPU pentru n
operaii Pune-n-Stiv?

c. Care este, n cel mai defavorabil caz, numrul de accese la disc i timpul CPU pentru n
operaii asupra stivei?

Presupunem c realizm o implementare a stivei n care se pstreaz dou pagini disc n memorie
(cu gestiunea aferent lor).

d. Descriei cum se gestioneaz, n acest caz, paginile stivei, astfel nct numrul amortizat
al acceselor de disc s fie O(1/m), iar timpul mediu amortizat CPU s fie O(1).

19-2 Fuzionarea i divizarea 2-3-4 arborilor


Operaia de