Cormen - romaneste

Embed Size (px)

Citation preview

  • 7/31/2019 Cormen - romaneste

    1/894

  • 7/31/2019 Cormen - romaneste

    2/894

    Titlul original: Introduction to Algorithms

    Copyright c 1990 Massachusetts Institute of TechnologyEditor coordonator: Clara Ionescu

    Coordonator traducere: Horia F. Pop

    Traducere:Prefaa: Simona Motogna Capitolul 19: Florian M. BoianCapitolul 1: Horia F. Pop Capitolul 20: Ioan LazarCapitolul 2: Paul Blaga Capitolul 21: Ioan Lazar

    Capitolul 3: Paul Blaga Capitolul 22: Virginia NiculescuCapitolul 4: Paul Blaga Capitolul 23: Adrian MoneaCapitolul 5: Adrian Monea Capitolul 24: Adrian MoneaCapitolul 6: Radu Trmbia Capitolul 25: Luminia StateCapitolul 7: Clara Ionescu Capitolul 26: Mihai ScoraruCapitolul 8: Zoltn Ksa Capitolul 27: Zoltn Ksa, Simona MotognaCapitolul 9: Luminia State Capitolul 28: Zoltn KsaCapitolul 10: Luminia State Capitolul 29: Florian M. BoianCapitolul 11: Simona Motogna Capitolul 30: Mihai ScoraruCapitolul 12: Simona Motogna Capitolul 31: Liviu NegrescuCapitolul 13: Bazil Prv Capitolul 32: Radu TrmbiaCapitolul 14: Bazil Prv Capitolul 33: Liviu NegrescuCapitolul 15: Bazil Prv Capitolul 34: Liana Bozga

    Capitolul 16: Cristina Vertan Capitolul 35: Liana BozgaCapitolul 17: Cristina Vertan Capitolul 36: Mihai ScoraruCapitolul 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 AgoraISBN 973-97534-7-7

  • 7/31/2019 Cormen - romaneste

    3/894

    Cuprins

    Prefaa ediiei n limba romn ix

    Prefa xi

    1. Introducere 11.1. Algoritmi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2. Analiza algoritmilor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51.3. Proiectarea algoritmilor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101.4. Rezumat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

    I. Fundamente matematice 18

    2. Creterea funciilor 202.1. Notaia asimptotic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202.2. Notaii standard i funcii comune . . . . . . . . . . . . . . . . . . . . . . . . . . 28

    3. Sume 373.1. Formule de nsumare i proprieti . . . . . . . . . . . . . . . . . . . . . . . . . . 373.2. Delimitarea sumelor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

    4. Recurene 464.1. Metoda substituiei . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

    4.2. Metoda iteraiei . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504.3. Metoda master . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 534.4. Demonstraia teoremei master . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

    5. Mulimi etc. 665.1. Mulimi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 665.2. Relaii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 705.3. Funcii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 725.4. Grafuri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 745.5. Arbori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

  • 7/31/2019 Cormen - romaneste

    4/894

    iv Cuprins

    6. Numrare i probabilitate 866.1. Numrare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 866.2. Probabilitate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 916.3. Variabile aleatoare discrete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 966.4. Distribuia geometric i distribuia binomial . . . . . . . . . . . . . . . . . . . 1006.5. Cozile distribuiei binomiale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1046.6. Analiz probabilistic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

    II. Ordonare i statistici de ordine 116

    7. Heapsort 1197.1. Heap-uri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1197.2. Reconstituirea proprietii de heap . . . . . . . . . . . . . . . . . . . . . . . . . . 1217.3. Construirea unui heap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1237.4. Algoritmul heapsort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1257.5. Cozi de prioriti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126

    8. Sortarea rapid 1318.1. Descrierea sortrii rapide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1318.2. Performana algoritmului de sortare rapid . . . . . . . . . . . . . . . . . . . . . 1338.3. Variantele aleatoare ale sortrii rapide . . . . . . . . . . . . . . . . . . . . . . . . 1378.4. Analiza algoritmului de sortare rapid . . . . . . . . . . . . . . . . . . . . . . . . 139

    9. Sortare n timp liniar 1479.1. Margini inferioare pentru sortare . . . . . . . . . . . . . . . . . . . . . . . . . . . 1479.2. Sortarea prin numrare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1499.3. Ordonare pe baza cifrelor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1529.4. Ordonarea pe grupe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154

    10.Mediane i statistici de ordine 15810.1. Minim i maxim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15810.2. Selecia n timp mediu liniar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15910.3. Selecia n timp liniar n cazul cel mai defavorabil . . . . . . . . . . . . . . . . . . 161

    III. Structuri de date 167

    11.Structuri de date elementare 17111.1. Stive i cozi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17111.2. Liste nlnuite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17411.3. Implementarea pointerilor i obiectelor . . . . . . . . . . . . . . . . . . . . . . . . 17811.4. Reprezentarea arborilor cu rdcin . . . . . . . . . . . . . . . . . . . . . . . . . 182

    12.Tabele de dispersie 18712.1. Tabele cu adresare direct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18712.2. Tabele de dispersie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18912.3. Funcii de dispersie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193

  • 7/31/2019 Cormen - romaneste

    5/894

    Cuprins v

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

    13.Arbori binari de cutare 20813.1. Ce este un arbore binar de cutare? . . . . . . . . . . . . . . . . . . . . . . . . . 20813.2. Interogarea ntr-un arbore binar de cutare . . . . . . . . . . . . . . . . . . . . . 21013.3. Inserarea i tergerea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21413.4. Arbori binari de cutare construii aleator . . . . . . . . . . . . . . . . . . . . . . 217

    14.Arbori rou-negru 22614.1. Proprietile arborilor rou-negru . . . . . . . . . . . . . . . . . . . . . . . . . . . 22614.2. Rotaii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228

    14.3. Inserarea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23014.4. tergerea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234

    15.mbogirea structurilor de date 24315.1. Statistici dinamice de ordine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24315.2. Cum se mbogete o structur de date . . . . . . . . . . . . . . . . . . . . . . . 24815.3. Arbori de intervale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251

    IV. Tehnici avansate de proiectare i analiz 257

    16.Programarea dinamic 25916.1. nmulirea unui ir de matrice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260

    16.2. Elemente de programare dinamic . . . . . . . . . . . . . . . . . . . . . . . . . . 26616.3. Cel mai lung subir comun . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27016.4. Triangularea optim a poligoanelor . . . . . . . . . . . . . . . . . . . . . . . . . . 275

    17.Algoritmi greedy 28317.1. O problem de selectare a activitilor . . . . . . . . . . . . . . . . . . . . . . . . 28317.2. Elemente ale strategiei greedy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28717.3. Coduri Huffman . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29017.4. Bazele teoretice ale metodei greedy . . . . . . . . . . . . . . . . . . . . . . . . . . 29617.5. O problem de planificare a activitilor . . . . . . . . . . . . . . . . . . . . . . . 301

    18.Analiza amortizat 30618.1. Metoda de agregare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30618.2. Metoda de cotare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31018.3. Metoda de potenial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31218.4. Tabele dinamice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315

    V. Structuri de date avansate 325

    19.B-arbori 32819.1. Definiia B-arborelui . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33019.2. Operaii de baz n B-arbore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33319.3. tergerea unei chei dintr-un B-arbore . . . . . . . . . . . . . . . . . . . . . . . . . 339

  • 7/31/2019 Cormen - romaneste

    6/894

    vi Cuprins

    20.Heap-uri binomiale 34420.1. Arbori binomiali i heap-uri binomiale . . . . . . . . . . . . . . . . . . . . . . . . 34520.2. Operaii pe heap-uri binomiale . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349

    21.Heap-uri Fibonacci 36221.1. Structura heap-urilor Fibonacci . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36321.2. Operaiile heap-urilor interclasabile . . . . . . . . . . . . . . . . . . . . . . . . . . 36421.3. Descreterea unei chei i tergerea unui nod . . . . . . . . . . . . . . . . . . . . . 37221.4. Mrginirea gradului maxim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374

    22.Structuri de date pentru mulimi disjuncte 379

    22.1. Operaii pe mulimi disjuncte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37922.2. Reprezentarea mulimilor disjuncte prin liste nlnuite . . . . . . . . . . . . . . . 38122.3. Pduri de mulimi disjuncte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38422.4. Analiza reuniunii dup rang comprimnd drumul . . . . . . . . . . . . . . . . . . 388

    VI. Algoritmi de grafuri 398

    23.Algoritmi elementari de grafuri 40023.1. Reprezentrile grafurilor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40023.2. Cutarea n lime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40323.3. Cutarea n adncime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41023.4. Sortarea topologic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41723.5. Componente tare conexe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420

    24.Arbori de acoperire minimi 42824.1. Dezvoltarea unui arbore de acoperire minim . . . . . . . . . . . . . . . . . . . . . 42924.2. Algoritmii lui Kruskal i Prim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433

    25.Drumuri minime de surs unic 44125.1. Drumuri minime i relaxare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44525.2. Algoritmul Dijkstra . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45225.3. Algoritmul Bellman-Ford . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45625.4. Drumuri minime de surs unic n grafuri orientate aciclice . . . . . . . . . . . . 46025.5. Constrngeri cu diferene i drumurile minime . . . . . . . . . . . . . . . . . . . . 462

    26.Drumuri minime ntre toate perechile de vrfuri 47326.1. Drumuri minime i nmulirea matricelor . . . . . . . . . . . . . . . . . . . . . . . 47526.2. Algoritmul Floyd-Warshall . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48026.3. Algoritmul lui Johnson pentru grafuri rare . . . . . . . . . . . . . . . . . . . . . . 48626.4. O modalitate general pentru rezolvarea problemelor de drum n grafuri orientate 490

    27.Flux maxim 49827.1. Reele de transport . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49827.2. Metoda lui Ford-Fulkerson . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50527.3. Cuplaj bipartit maxim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515

  • 7/31/2019 Cormen - romaneste

    7/894

    Cuprins vii

    27.4. Algoritmi de preflux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51927.5. Algoritmul mutare-n-fa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 527

    VII. Capitole speciale 541

    28.Reele de sortare 54428.1. Reele de comparare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54428.2. Principiul zero-unu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54828.3. O reea de sortare a secvenelor bitone . . . . . . . . . . . . . . . . . . . . . . . . 55028.4. Reeaua de interclasare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 552

    28.5. Reeaua de sortare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55529.Circuite aritmetice 561

    29.1. Circuite combinaionale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56129.2. Circuite de sumare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56629.3. Circuite multiplicatoare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57529.4. Circuite cu ceas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 581

    30.Algoritmi pentru calculatoare paralele 59030.1. Saltul de pointer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59330.2. Algoritmi CRCW i algoritmi EREW . . . . . . . . . . . . . . . . . . . . . . . . 60130.3. Teorema lui Brent i eficiena efortului . . . . . . . . . . . . . . . . . . . . . . . . 60830.4. Calculul paralel de prefix, eficient ca efort . . . . . . . . . . . . . . . . . . . . . . 612

    30.5. ntreruperi deterministe de simetrie . . . . . . . . . . . . . . . . . . . . . . . . . . 617

    31.Operaii cu matrice 62631.1. Proprietile matricelor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62631.2. Algoritmul lui Strassen pentru nmulirea matricelor . . . . . . . . . . . . . . . . 63331.3. Sisteme de numere algebrice i nmulirea matricelor booleene . . . . . . . . . . . 63831.4. Rezolvarea sistemelor de ecuaii liniare . . . . . . . . . . . . . . . . . . . . . . . . 64231.5. Inversarea matricelor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65331.6. Matrice simetrice pozitiv-definite i aproximarea prin

    metoda celor mai mici ptrate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 657

    32.Polinoame i TFR 666

    32.1. Reprezentarea polinoamelor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66732.2. TFD i TFR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67332.3. Implementri eficiente ale TFR . . . . . . . . . . . . . . . . . . . . . . . . . . . . 679

    33.Algoritmi din teoria numerelor 68733.1. Noiuni elementare de teoria numerelor . . . . . . . . . . . . . . . . . . . . . . . 68833.2. Cel mai mare divizor comun . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69333.3. Aritmetic modular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69733.4. Rezolvarea ecuaiilor liniare modulare . . . . . . . . . . . . . . . . . . . . . . . . 70233.5. Teorema chinez a restului . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70533.6. Puterile unui element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 708

  • 7/31/2019 Cormen - romaneste

    8/894

    viii Cuprins

    33.7. Criptosistemul RSA cu cheie public . . . . . . . . . . . . . . . . . . . . . . . . . 71133.8. Testul de primalitate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71733.9. Factorizarea ntreag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 724

    34.Potrivirea irurilor 73134.1. Algoritmul naiv pentru potrivirea irurilor . . . . . . . . . . . . . . . . . . . . . . 73234.2. Algoritmul Rabin-Karp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73534.3. Potrivirea irurilor folosind automate finite . . . . . . . . . . . . . . . . . . . . . 73934.4. Algoritmul Knuth-Morris-Pratt . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74534.5. Algoritmul Boyer-Moore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 751

    35.Geometrie computaional 75935.1. Proprietile segmentului de dreapt . . . . . . . . . . . . . . . . . . . . . . . . . 75935.2. Determinarea cazului n care oricare dou segmente se intersecteaz . . . . . . . 76435.3. Determinarea nvelitorii convexe . . . . . . . . . . . . . . . . . . . . . . . . . . . 76935.4. Determinarea celei mai apropiate perechi de puncte . . . . . . . . . . . . . . . . . 778

    36.NP-completitudine 78536.1. Timpul polinomial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78636.2. Verificri n timp polinomial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79236.3. NP-completitudine i reductibilitate . . . . . . . . . . . . . . . . . . . . . . . . . 79636.4. Demonstraii ale NP-completitudinii . . . . . . . . . . . . . . . . . . . . . . . . . 80436.5. Probleme NP-complete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 810

    37.Algoritmi de aproximare 82637.1. Problema acoperirii cu vrfuri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82837.2. Problema comis-voiajorului . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83037.3. Problema acoperirii mulimii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83437.4. Problema sumei submulimii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 838

    Bibliografie 845

    Index 853

  • 7/31/2019 Cormen - romaneste

    9/894

    Prefaa ediiei n limba romn

    Ani de zile am visat apariia acestei cri. tiu c muli profesori, elevi i studeni au cutatlucrarea semnat de Thomas H. Cormen, Charles E. Leiserson i Ronald L. Rivest n originalsau diverse traduceri ale ei. Unii, mai norocoi, au reuit poate s mprumute cartea din diverselocuri, pentru scurte perioade de timp. Dar aceast carte conine un volum foarte mare decunotine 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 doamneiCristina Sanmartin (MIT Press) c ne-a ncurajat i a intermediat semnarea contractuluipentru 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 mulumiriprofesorilor de la Universitatea Babe-Bolyai i de la Universitatea Bucureti, studenilor iprietenilor care au sacrificat multe ore din timpul lor liber, pentru ca dumneavoastr s puteiine aceast carte n mn.

    Domnul confereniar dr. Horia F. Pop, de la Universitatea Babe-Bolyai, Facultatea deMatematic i Informatic, a coordonat traducerea, a stabilit mpreun cu traductorii modulde traducere a termenilor de specialitate noi, ncepnd cu index-ul, pentru a asigura o traducerecoerent, omogen i pe ct posibil unitar. De asemenea, a pregtit i coordonat utilizarea dectre traductori a sistemului LATEX.

    Am lucrat cu cadre didactice universitare de specialitate deoarece o asemenea carte nu setraduce doar cu lingviti, este nevoie de specialiti din domeniu care neleg foarte bine coninutultiinific 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, profesordr. 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 Negrescude la Universitatea Tehnic din Cluj, domnului profesor dr. Horia Georgescu de la Academia deStudii Economice, doamnei profesor dr. Luminia State de la Universitatea din Piteti, doamneilector drd. Cristina Vertan, de la Universitatea Bucureti i nu n ultimul rnd studenilor AdrianMonea i Mihai Scoraru, de la Universitatea Tehnic din Cluj.

    Cum aceasta este prima carte editat de Computer Libris Agora n LATEX, tehnoredactareaa constituit i ea un efort. n special pregtirea desenelor a ridicat multe probleme, graficianul

  • 7/31/2019 Cormen - romaneste

    10/894

    x

    nostru Dan Creu lucrnd nenumrate ore la realizarea acestora. Asistena tehnic n domeniulpregtirii 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 rugms ne transmitei observaiile i sugestiile dumneavoastr pe adresa de e-mail:

    [email protected]

    sau pe adresa editurii:

    Urmnd exemplul american, lista cu greelile gsite va fi disponibil pe Internet. Cei caredoresc s intre n posesia ultimei erate pot trimite un mesaj la adresa [email protected] expresia erata algoritmi n cmpul Subject i vor primi automat ultima versiune nformat 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 imbogit. V promitem c, imediat ce aceast versiune va fi disponibil pentru traducere, ovom publica i n limba romn.

  • 7/31/2019 Cormen - romaneste

    11/894

    Prefa

    Aceast carte se dorete a fi o introducere exhaustiv n studiul modern al algoritmilor. Eaprezint muli algoritmi i i studiaz n profunzime, pstrnd totui analiza i proiectarea lor laun nivel accesibil tuturor cititorilor. Am ncercat s pstrm explicaiile la un nivel elementarfr a afecta profunzimea abordrii sau rigoarea matematic.

    Fiecare capitol prezint un algoritm, o tehnic de proiectare, o arie de aplicare sau unsubiect legat de acestea. Algoritmii sunt descrii n englez i n pseudocod, care a fost astfelconceput 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. Deoarececonsiderm ca un criteriu de baz n proiectare, vom include analiza atent a timpilorde execuie a algoritmilor prezentai.

    Cartea se adreseaz, n primul rnd, celor care studiaz un curs elementar sau academic dealgoritmi 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 utilpentru diverse cursuri, de la un curs elementar de structuri de date pn la un curs academicde algoritmi. Deoarece am adunat considerabil mai mult material dect poate ncpea ntr-uncurs obinuit de un semestru, cartea poate fi privit ca un depozit din care se poate alegematerialul 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 neateptatsau 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 cursavansat se poate parcurge ntreg capitolul.

    Am inclus peste 900 de exerciii i peste 120 de probleme. Fiecare seciune se ncheie cuexerciii, iar fiecare capitol cu probleme. Exerciiile sunt, n general, ntrebri scurte care testeazstpnirea noiunilor de baz prezentate. Unele dintre ele sunt simple verificri, n timp ce altelesunt potrivite ca teme de cas. Problemele reprezint studii de caz mult mai elaborate, care demulte ori introduc noiuni noi; n general, constau din mai multe ntrebri care conduc studentulprin paii necesari pentru a ajunge la o soluie.

    Am notat cu (*) seciunile i exerciiile care se adreseaz mai degrab studenilor avansaidect celor nceptori. O seciune marcat cu (*) nu este n mod necesar mai dificil dect

  • 7/31/2019 Cormen - romaneste

    12/894

    xii Prefa

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

    Pentru studeni

    Sperm ca textul acestei cri s ofere o introducere plcut n domeniul algoritmilor. Amintenionat s prezentm fiecare algoritm ntr-o manier accesibil i interesant. Pentru a fi unajutor cnd ntlnii algoritmi neobinuii sau dificili, am descris fiecare algoritm pas cu pas.De asemenea, am oferit explicaii detaliate a noiunilor matematice necesare nelegerii analizeialgoritmilor. Dac deja dispunei de cunotine relative la un anumit subiect, atunci vei gsicapitolele organizate astfel nct putei frunzri seciunile introductive i s v concentrai asupranoiunilor 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 referinteoretic 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 nelegeiprocedurile recursive i structurile de date simple, ca tablouri sau liste nlnuite.

    Este necesar o anumit experien n demonstraii prin inducie matematic. Uneleporiuni 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 dealgoritmi. Deoarece fiecare capitol este conceput relativ independent, v putei concentra doarasupra 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, ampropus alternative practice puinilor algoritmi care prezint interes primordial teoretic.

    Dac dorii s implementai oricare dintre algoritmi, vei constata c transcrierea algortimilordin 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 necesitpresupuneri specifice relative unor medii de programare. Am urmrit s prezentm fiecarealgoritm 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. Dacdescoperii o eroare sau avei unele sugestii constructive, am aprecia s ni le mprtii. Suntbinevenite, n mod special, sugestii pentru noi exerciii i probleme, dar v rugm s includei isoluiile. Le putei trimite prin pot, pe adresa:

  • 7/31/2019 Cormen - romaneste

    13/894

    xiii

    MIT Laboratory for Computer Science545 Technology SquareCambridge, Massachusetts 02139Sau, 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 [email protected] cu Subject: help n antetul mesajului. Regretm c nuputem rspunde personal la toate mesajele.

    Mulumiri

    Mai muli prieteni i colegi au contribuit la calitatea acestei cri. Le mulumim tuturorpentru 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. nmod deosebit, colegii notri de la laboratorul Grupului de Teoria Calculatoarelor ne-au ajutati acceptat cererile noastre continue de parcurgere critic a capitolelor. Dorim s mulumimn mod special urmtorilor colegi: Baruch Awerbuch, Shafi Goldwasser, Leo Guibas, TomLeighton, Albert Meyer, David Shmoys i Eva Tardos. Mulumiri lui William Ang, Sally Bemus,Ray Hirschfeld i Mark Reinhold pentru ntreinerea calculatoarelor (DEC Microvax, AppleMacintosh i Sun Sparcstation) i pentru recompilarea TEX ori de cte ori am depit limitatimpului 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 dezvoltareaacestei cri. Mulumim n mod special urmtorilor: Alan Baratz, Bonnie Berger, Aditi Dhagat,Burt Kaliski, Arthur Lent, Andrew Moulton, Marios Papaefthymiou, Cindy Phillips, MarkReinhold, 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 petrecutmulte 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 bibliotecapersonal 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 iau schiat notie relative la rezolvarea lor. Marios Papaefthymiou i Gregory Troxel au contribuitla 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 specialurmtorilor: Bobby Blumofe, Bonnie Eisenberg, Raymond Johnson, John Keen, Richard Lethin,Mark Lillibridge, John Pezaris, Steve Ponzio i Margaret Tuttle pentru parcurgerile i corecturileefectuate.

    De asemenea, colegii notri au adus critici asupra anumitor capitole, ne-au oferit indicaiiasupra unor algoritmi specifici, motiv pentru care le suntem ndatorai. Mulumim n mod

  • 7/31/2019 Cormen - romaneste

    14/894

    xiv Prefa

    deosebit urmtorilor: Bill Aiello, Alok Aggarwal, Eric Bach, Vaek Chvtal, Richard Cole, JohanHastad, Alex Ishii, David Johnson, Joe Killian, Dina Kravets, Bruce Maggs, Jim Orlin, JamesPark, Thane Plambeck, Hershel Safer, Jeff Shallit, Cliff Stein, Gil Strang, Bob Tarjan i PaulWang. 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 desenatepe Apple Macintosh folosind MacDraw II; mulumim lui Joanna Terry de la Claris Corporationi lui Michael Mahoney de la Advanced Computer Graphics pentru sprijinul lor. Indexul afost compilat folosind Windex, un program C scris de autori. Bibliografia a fost pregtitfolosind BibTEX. Cartea a fost tiprit la American Mathematical Society cu ajutorul uneimaini Autologic; mulumim lui Ralph Youngen de la AMS pentru ajutorul dat. Coperta criia fost conceput de Jeannet Leendertse. Design-ul crii a fost creat de Rebecca Daw, iar AmyHendrickson l-a implementat n LATEX.

    Colaborarea cu MIT Press i McGraw-Hill a fost deosebit de plcut. Mulumim n modspecial urmtorilor: Frank Satlow, Terry Ehling, Larry Cohen i Lorrie Lejeune de la MIT Pressi David Shapiro de la McGraw-Hill pentru ncurajri, sprijin i rbdare. Suntem deosebit derecunosctori 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 pentrudragostea i sprijinul lor pe ntreaga durat a scrierii acestei cri. (Alex Rivest ne-a ajutat nmod special cu Paradoxul zilei de natere a marianului). Dragostea, rbdarea i ncurajareadin partea familiilor noastre au fcut acest proiect posibil. Le dedicm din suflet aceast carte lor.

    Thomas H. CormenCharles E. LeisersonRonald L. Rivest

  • 7/31/2019 Cormen - romaneste

    15/894

    1 Introducere

    Acest capitol v va familiariza cu conceptele de baz folosite n aceast carte, referitor laproiectarea i analiza algoritmilor. Este un text, practic, independent de restul crii, dar includecteva referiri la materialul care va fi introdus n partea I.

    ncepem cu o discuie asupra problemelor generale ale calculabilitii i ale algoritmilornecesari pentru rezolvarea acestora, cu problema sortrii, ca exemplu introductiv. Pentru aarta cum vom specifica algoritmii prezentai, vom introduce un pseudocod, care ar trebui

    s fie familiar cititorilor obinuii cu programarea. Sortarea prin inserie, un algoritm simplude sortare, va servi ca exemplu iniial. Vom analiza timpul de execuie pentru sortarea prininserie, introducnd o notaie care s descrie modul n care crete acest timp o dat cu numrulobiectelor aflate n operaia de sortare. De asemenea, vom introduce n proiectarea algoritmilormetoda , pe care o vom utiliza pentru dezvoltarea unui algoritm numit sortareprin 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 definitcare 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 paicare transform datele de intrare n date de ieire.

    Putem, de asemenea, s privim un algoritm ca pe un instrument de rezolvare a problemelorde calcul bine definite. Enunul problemei specific, n termeni generali, relaia doritintrare/ieire. Algoritmul descrie o anumit procedur de calcul pentru a se ajunge la aceastlegtur 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 pentruintroducerea multor metode standard pentru proiectarea i analiza algoritmilor. Iat cum vomdefini formal problema sortrii:

    Date de intrare: Un ir de n numere a1, a2, . . . , an.

    Date de ieire: O permutare (reordonare) a irului iniial, a1, a2, . . . , an astfel nct a1 a2 an.

    Fiind dat un ir de intrare, ca, de exemplu, 31, 41, 59, 26, 41, 58, un algoritm de sortarereturneaz, la ieire, irul 26, 31, 41, 41, 58, 59. Un ir de intrare ca cel de mai sus se numeteo instan a problemei de sortare. n general, prin instan a unei probleme se va nelegemulimea 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 pasintermediar) i, ca urmare, a fost dezvoltat un numr mare de algoritmi de sortare. Care algoritmeste cel mai bun pentru o aplicaie dat depinde de numrul de obiecte care trebuie sortate, de

  • 7/31/2019 Cormen - romaneste

    16/894

    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 electroniccare 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-arputea s nu se termine deloc n cazul unor anumite instane de intrare, sau s-ar putea terminaproducnd 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 capitolul33, cnd vom studia algoritmi pentru gsirea numerelor prime foarte mari. Totui, n general nevom ocupa doar de algoritmi coreci.

    Concret, un algoritm poate fi specificat printr-un program pentru calculator sau chiar ca unechipament hardware. Singura condiie este aceea ca specificaiile s produc o descriere precisa procedurii de calcul care urmeaz a fi parcurs.

    n aceast carte vom descrie algoritmii sub forma unor programe scrise ntr-un pseudocodcare seamn foarte mult cu limbajele C, Pascal sau Algol. Dac suntei ct de ct familiarizaicu oricare dintre acestea, nu vei avea probleme n a citi algoritmii notri. Ceea ce difereniazcodul real de pseudocod este faptul c vom folosi metoda cea mai clar i mai concis pentru adescrie un algoritm dat. O alt diferen dintre pseudocod i codul real este aceea c pseudocodulnu 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 unuinumr mic de obiecte. Sortarea prin inserie funcioneaz n acelai fel n care muli oamenisorteaz un pachet de cri de joc obinuite. Se ncepe cu pachetul aezat pe mas cu faa n josi cu mna stng goal. Apoi, lum cte o carte de pe mas i o inserm n poziia corect nmna stng. Pentru a gsi poziia corect pentru o carte dat, o comparm cu fiecare dintrecrile aflate deja n mna stng, de la dreapta la stnga, aa cum este ilustrat n figura 1.1.

  • 7/31/2019 Cormen - romaneste

    17/894

    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 careurmeaz a fi sortat. (Pe parcursul codului, numrul de elemente ale lui A este notat prin

    [A].) Numerele de intrare sunt sortate pe loc, n cadrul aceluiai vector A; cel multun numr constant dintre acestea sunt memorate n zone de memorie suplimentare. CndSorteaz-Prin-Inserie se termin, vectorul iniial A va conine elementele irului de ieiresortat.

    Sorteaz-Prin-Inserie(A)1: pentru j 2, [A] execut2:

    A[j]

    3: Insereaz A[j] n irul sortat A[1..j 1]4: i j 15: ct timp i > 0 i A[i] > execut6: A[i + 1] A[i]7: i i 18: A[i + 1]

    Figura 1.2 ilustreaz modul de funcionare a acestui algoritm pentru A = 5, 2, 4, 6, 1, 3.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] corespundpachetului de cri aflate nc pe mas. Indicele se deplaseaz de la stnga la dreapta n interiorulvectorului. 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 gsitpoziia 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 nlinia 1, const din liniile 28 iar corpul ciclului ct timp, care ncepe n linia 5, conineliniile 67, dar nu i linia 8. Stilul nostru de indentare se aplic i structurilor de tipuldac-atunci-altfel. Folosirea indentrii n locul unor indicatori de bloc de tipul begin iend, reduce cu mult riscul de confuzie, mbuntind claritatea prezentrii.1

    2. Ciclurile de tipul ct timp, pentru, repet i construciile condiionale dac, atunci ialtfel 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 ambelorvariabile i i j; aceasta ar trebui tratat ca un echivalent al atribuirii j e, urmat deatribuirea i j.

    n limbajele de programare reale, indentarea, ca unic metod pentru indicarea structurilor de bloc, nu esten general recomandabil, deoarece nivelurile de indentare se determin greoi n cazul unor coduri care se continupe mai multe pagini.

  • 7/31/2019 Cormen - romaneste

    18/894

    4 Capitolul 1 Introducere

    Figura 1.2 Modul de operare a procedurii Sorteaz-Prin-Inserie asupra vectorului A =5, 2, 4, 6, 1, 3. Poziia indicelui j este indicat printr-un cerc.

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

    6. Elementele unui vector sunt accesate specificnd numele vectorului urmat de indice nparanteze 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 obiectuluisu n paranteze drepte. De exemplu, tratm un vector ca pe un obiect cu atributulindicnd numrul de elemente ale acestuia. Pentru a specifica numrul de elemente ale unuivector A, se va scrie [A]. Dei vom folosi parantezele drepte att pentru indexareaelementelor unui vector, ct i pentru atributele obiectelor, va fi clar din context care esteinterpretarea corect.

    O variabil reprezentnd un vector sau un obiect este tratat ca un pointer spre datelecare reprezint vectorul sau obiectul. Pentru toate cmpurile f ale unui obiect x, atribuireay

    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 (sausunt) acelai obiect dup atribuirea y x. Uneori, un pointer nu se va referi la nici unobiect. 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 estevzut de procedura apelant. Cnd obiectele sunt transmise procedurii, este copiat doarpointerul spre datele reprezentnd obiectul, nu i cmpurile acestuia. De exemplu, dac xeste un parametru al unei proceduri apelate, atribuirea x y n cadrul procedurii apelatenu este vizibil din procedura apelant. Atribuirea f[x] 3 este, totui, vizibil.

  • 7/31/2019 Cormen - romaneste

    19/894

    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 = 31, 41, 59, 26, 41, 58.

    1.1-2 Rescriei procedura Sorteaz-Prin-Inserie pentru a sorta n ordine necresctoare nloc de ordine nedescresctoare.

    1.1-3 S considerm problema cutrii:

    Date de intrare: Un ir de n numere A = a1, a2, . . . , an i o valoare v.

    Date de ieire: Un indice i astfel nct v = A[i] sau valoarea special nil dac v nu apare nA.

    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 vectorin-dimensionali A i B. Suma celor doi ntregi trebuie s fie memorat n form binar ntr-unvector C avnd n + 1 elemente. Gsii un enun formal al problemei i scriei un algoritm pentruadunarea 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 identificatuor. O astfel de analiz poate indica mai muli candidai viabili, dar civa algoritmi inferiorisunt, de obicei, eliminai n timpul analizei.

    nainte de a analiza un algoritm, trebuie s avem un model al tehnologiei de implementare careurmeaz 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 unmodel 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, npartea 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 abilitateade a identifica cei mai importani termeni ntr-o expresie. Deoarece comportarea unui algoritmpoate fi diferit n funcie de datele de intrare, avem nevoie de un mijloc de exprimare a acesteicomportri n formule simple, uor de neles.

    Dei, pentru a analiza un algoritm, selectm numai un anumit tip de model de main decalcul, rmn mai multe posibiliti de alegere a felului n care decidem s exprimm aceastanaliz. Un scop imediat este de a gsi un mijloc de exprimare care s fie simplu de scris i demanevrat, care s arate principalele resurse necesare unui algoritm i s suprime detaliile inutile.

  • 7/31/2019 Cormen - romaneste

    20/894

    6 Capitolul 1 Introducere

    Analiza sortrii prin inserie

    Timpul de execuie necesar procedurii Sorteaz-Prin-Inserie depinde de intrare: sortareaa 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 aceeaidimensiune, 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 estetradiional s se descrie timpul de execuie al unui program n funcie de dimensiunea datelor deintrare. n acest scop, trebuie s definim cu mai mult precizie termenii de timp de execuie idimensiune 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 naturalmsur este de exemplu, pentru sortare, un vectorde dimensiune n. Pentru multe alte probleme, ca spre exemplu nmulirea a doi ntregi, ceamai bun msur pentru dimensiunea datelor de intrare este necesaripentru reprezentarea datelor de intrare n notaie binar. Uneori, este mai potrivit s exprimmdimensiunea datelor de intrare prin dou numere n loc de unul. De exemplu, dac datele deintrare ale unui algoritm sunt reprezentate de un graf, dimensiunea datelor de intrare poate fidescris prin numrul de vrfuri i muchii ale grafului. Pentru fiecare problem pe care o vomstudia, vom indica msura utilizat pentru dimensiunea datelor de intrare.

    Timpul de execuie a unui algoritm pentru un anumit set de date de intrare este determinatde numrul de operaii primitive sau pai executai. Este util s definim noiunea de pas astfelnct 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. Oanumit linie poate avea nevoie de un timp de execuie diferit dect o alta, dar vom presupune cfiecare execuie a liniei i consum timpul ci, unde ci este o constant. Acest punct de vedere esteconform cu modelul RAM i, n acelai timp, reflect, destul de bine, modul n care pseudocodulpoate fi, de fapt, utilizat n cele mai multe cazuri concrete.2

    n prezentarea care urmeaz, expresia noastr pentru timpul de execuie al algoritmuluiSorteaz-Prin-Inserie va evolua de la o formul relativ complicat, care folosete toatecosturile de timp ci, la una mult mai simpl n notaii, care este mai concis i mai uor demanevrat. Aceast notaie mai simpl va face, de asemenea, uor de determinat dac un algoritmeste mai eficient dect altul.

    ncepem prin a relua prezentarea procedurii Sorteaz-Prin-Inserie, adugnd costulde timp pentru fiecare instruciune i un numr care reprezint de cte ori aceasta este efectiv

    executat. Pentru fiecare j = 2, 3, . . . , n, unde n = [A], vom nota cu tj numrul deexecuii ale testului ct timp din linia 5 pentru valoarea fixat j. Vom presupune c uncomentariu nu este o instruciune executabil, prin urmare nu cere timp de calcul.

    Timpul de execuie al algoritmului este suma tuturor timpilor de execuie corespunztori

    Exist aici cteva subtiliti: paii de calcul pe care i precizm sunt, cel mai adesea, variante ale unorproceduri care cer mai mult dect doar un timp constant. De exemplu, n continuare, n aceast carte am puteaspune, ntr-o linie de pseudocod, sorteaz punctele conform coordonatei x, care, aa cum vom vedea, cere maimult dect un timp constant. De asemenea, se poate observa c o instruciune care apeleaz o subrutin arenevoie de un timp constant, dei subrutina, o dat apelat, are nevoie de mai mult timp de execuie. Din acestmotiv, separm procesul de a apela o subrutin trecerea parametrilor ctre aceasta etc. de procesul de aexecuta subrutina.

  • 7/31/2019 Cormen - romaneste

    21/894

    1.2. Analiza algoritmilor 7

    Sorteaz-Prin-Inserie(A)1: pentru j 2, [A] execut2: A[j]3: Insereaz A[j] n irul sortat A[1..j 1]4: i j 15: ct timp i > 0 i A[i] > execut6: A[i + 1] A[i]7: i i 18: A[i + 1]

    c1 nc2 n 10 n 1c4 n 1c5

    nj=2 tj

    c6n

    j=2(tj 1)c7

    nj=2(tj 1)

    c8 n 1

    fiecrei instruciuni executate: o instruciune care consum timpul ci pentru execuie i esteexecutat de n ori, va contribui cu cin la timpul total de execuie.3 Pentru a calcula T(n),timpul de execuie pentru Sorteaz-Prin-Inserie, vom aduna produsele mrimilor indicaten coloanele i , obinnd

    T(n) = c1n + c2(n 1) + c4(n 1) + c5nj=2

    tj + c6

    nj=2

    (tj 1) + c7nj=2

    (tj 1)

    + c8(n 1).

    Chiar pentru date de intrare de aceeai mrime, timpul de execuie al unui algoritm dat poates depind de datelor de intrare. De exemplu, pentru Sorteaz-Prin-Inserie, cazulcel mai favorabil apare cnd vectorul de intrare este deja sortat. Pentru fiecare j = 2, 3 . . . , n,

    vom gsi c A[i] n linia 5, cnd i are valoarea iniial j 1. Rezult tj = 1 pentruj = 2, 3, . . . , n i timpul de execuie n cazul cel mai favorabil este

    T(n) = c1n + 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 a i b caredepind 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 cazulcel mai defavorabil. n aceast situaie trebuie s comparm fiecare element A[j] cu fiecareelement din subvectorul A[1..j 1], i, astfel, tj = j pentru j = 2, 3, . . . , n. Observnd c

    nj=2

    j = n(n + 1)2 1

    i

    nj=2

    (j 1) = n(n 1)2

    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 mncuvinte de memorie.

  • 7/31/2019 Cormen - romaneste

    22/894

    8 Capitolul 1 Introducere

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

    T(n) = c1n + c2(n 1) + c4(n 1) + c5

    n(n + 1)

    2 1

    + c6

    n(n 1)

    2

    + c7

    n(n 1)

    2

    + c8(n 1)

    =c5

    2+

    c62

    +c72

    n2 +

    c1 + c2 + c4 +

    c52

    c62

    c72

    + c8

    n

    (c2 + c4 + c5 + c8) .

    Rezult c timpul de execuie n cazul cel mai defavorabil poate fi exprimat sub formaan2 + bn + c, unde constantele a, b i c depind, din nou, de costurile ci ale instruciunilor, fiindastfel o funcie ptratic de n.

    De obicei, la fel ca la sortarea prin inserie, timpul de execuie al unui algoritm dat estefix pentru anumite date de intrare. Totui, n ultimele capitole, vom ntlni civa algoritmialeatori 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, ncare vectorul de intrare era deja sortat, respectiv cel mai defavorabil, n care vectorul de intrareera sortat n ordine invers. n continuare (pe tot parcursul acestei cri), ne vom concentra, deregul, pe gsirea timpului de execuie n cazul cel mai defavorabil, cu alte cuvinte, acelui mai mare timp de execuie posibil relativ la date de intrare de dimensiune constantn. Precizm trei motive pentru aceast orientare:

    Timpul de execuie al unui algoritm n cazul cel mai defavorabil este o margine superioara timpului de execuie pentru orice date de intrare de dimensiune fix. Cunoscnd acesttimp, 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 deexecuie 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 prezentn 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. Spresupunem c alegem la ntmplare n numere i aplicm sortarea prin inserie. Ct timpva 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], icealalt jumtate sunt mai mari. Prin urmare, n medie, trebuie verificate jumtate dinelementele subvectorului A[1..j1], 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 celmai defavorabil.

  • 7/31/2019 Cormen - romaneste

    23/894

    1.2. Analiza algoritmilor 9

    n anumite cazuri particulare, vom fi interesai de timpul mediu de execuie al unuialgoritm. O problem care apare n analiza cazului mediu este aceea c s-ar putea s nu fieprea 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. npractic, 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, folosindconstantele 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 maidefavorabil este de forma an2+bn+c pentru anumite constante a, b i c care depind de costurile ciale instruciunilor. Astfel, am ignorat nu numai costurile reale ale instruciunilor, dar i costurileabstracte ci.

    Vom face acum nc o abstractizare simplificatoare. Ceea ce ne intereseaz de fapt, este ratade cretere sau ordinul de cretere a timpului de execuie. Considerm, prin urmare, doartermenul dominant al formulei (adic an2) deoarece ceilali termeni sunt relativ nesemnificativipentru valori mari ale lui n. Ignorm, de asemenea, i factorul constant c, deoarece, pentrunumere foarte mari, factorii constani sunt mai puin semnificativi dect rata de cretere ndeterminarea eficienei computaionale a unor algoritmi. Astfel, vom spune, de exemplu, csortarea prin inserie are un timp de execuie n cazul cel mai defavorabil de (n2) (pronunatteta 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 sude execuie n cazul cel mai defavorabil are un ordin de cretere mai mic. Aceast evaluare arputea fi incorect pentru date de intrare de dimensiune mic, dar n cazul unor date de intrarede dimensiuni foarte mari, un algoritm de tipul (n2), de exemplu, va fi executat n cazul celmai 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 gsindcel mai mic element al lui A i punndu-l ca prim element ntr-un alt vector B. Apoi, gsim aldoilea element mai mic din A i l punem pe poziia a doua a lui B. Continuai n acelai modpentru 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 aleirului de intrare trebuie verificate, n medie, presupunnd c elementul cutat se afl printretermenii irului dat? Ce putei spune despre cazul cel mai defavorabil? Care sunt timpul mediude execuie i timpul de execuie n cazul cel mai defavorabil pentru cutarea liniar, exprimain notaia ? Justificai rspunsurile.

    1.2-3 S considerm problema evalurii unui polinom ntr-un punct. Fiind dai n coeficienia0, a1, . . . , an1 i un numr real x, dorim s calculm

    n1i=0 aix

    i. Descriei un algoritm simplu

  • 7/31/2019 Cormen - romaneste

    24/894

    10 Capitolul 1 Introducere

    n timp (n2) pentru aceast operaie. Descriei i un algoritm n timp (n) care foloseteurmtoarea metod de rescriere a unui polinom, numit schema lui Horner:

    n1i=0

    aixi = ( (an1x + an2)x + + a1)x + a0

    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 ncel mai favorabil caz?

    1.3. Proiectarea algoritmilor

    Exist multe moduri de proiectare a algoritmilor. Sortarea prin inserie folosete o metodcare s-ar putea numi incremental: avnd deja sortat subvectorul A[1..j1], inserm elementulA[j] n locul potrivit producnd subvectorul A[1..j].

    n aceast seciune vom examina o abordare diferit, numit . Vom utilizaaceast abordare pentru a construi un algoritm de sortare al crui timp de execuie n cazul celmai defavorabil va fi mult mai mic dect al celui corespunztor sortrii prin inserie. Unul dinavantajele algoritmilor de tipul este acela c timpul lor de execuie esteadesea 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 suntapelai 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 problemade rezolvat n mai multe probleme similare problemei iniiale, dar de dimensiune mai mic, lerezolv n mod recursiv i apoi le combin pentru a crea o soluie a problemei iniiale.

    Paradigma 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. Intuitiv, acesta opereaz astfel.

    Divide: mparte irul de n elemente care urmeaz a fi sortat n dou subiruri de cte n/2elemente.

    Stpnete: Sorteaz recursiv cele dou subiruri utiliznd sortarea prin interclasare.

    Combin: Interclaseaz cele dou subiruri sortate pentru a produce rezultatul final.

  • 7/31/2019 Cormen - romaneste

    25/894

    1.3. Proiectarea algoritmilor 11

    Figura 1.3 Modul de operare al sortrii prin interclasare asupra vectorului A = 5, 2, 4, 6, 1, 3, 2, 6.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 maiavem nimic de fcut, deoarece orice ir de lungime 1 este deja sortat.

    Operaia principal a algoritmului de sortare prin interclasare este interclasarea a dou irurisortate, 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, astfelnct p q < r. Procedura presupune c subvectorii A[p..q] i A[q + 1..r] sunt sortai. Ea iinterclaseaz 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), esteuor 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 nostrucu crile de joc, s presupunem c avem dou pachete de cri de joc aezate pe mas cu faan 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 pemas cu faa n jos. Pasul principal este acela de a selecta cartea cu valoarea cea mai mic dintrecele dou aflate deasupra pachetelor (fapt care va face ca o nou carte s fie deasupra pachetuluirespectiv) i de a o pune cu faa n jos pe locul n care se va forma pachetul sortat final. Repetmacest procedeu pn cnd unul din pachete este epuizat. n aceast faz, este suficient s lumpachetul 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 deoperaii elementare, timpul de execuie pentru procedura Interclaseaz este (n).

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

  • 7/31/2019 Cormen - romaneste

    26/894

    12 Capitolul 1 Introducere

    Sorteaz-Prin-Interclasare (A,p,r)1: dac p < r atunci2: q (p + r)/23: 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 dinsubvectorul A[p..r]. Dac p r, subvectorul are cel mult un element i este, prin urmare, dejasortat. 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

    n/2

    elemente i A[q+ 1..r] coninnd

    n/2

    elemente.4 Pentru a sorta ntregul ir A = A[1], A[2], . . . A[n], vom apela procedura Sortea-z-Prin-Interclasare sub forma Sorteaz-Prin-Interclasare(A, 1, [A]) unde, dinnou, [A] = n. Dac analizm modul de operare al procedurii, de jos n sus, cnd n esteo putere a lui 2, algoritmul const din interclasarea perechilor de iruri de lungime 1, pentru aforma iruri sortate de lungime 2, interclasarea acestora n iruri sortate de lungime 4, i aamai departe, pn cnd dou iruri sortate de lungime n/2 sunt interclasate pentru a forma irulsortat 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 deintrare de dimensiuni mai mici. Putem, apoi, folosi instrumente matematice pentru a rezolvaproblema 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 bazeazpe cele trei etape definite n descrierea metodei. La fel ca pn acum, vom nota cu T(n) timpulde 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, fiecaredintre acestea avnd dimensiunea de 1/b din dimensiunea problemei originale. Dac D(n) estetimpul necesar pentru a divide problema n subprobleme, iar C(n) este timpul necesar pentru acombina soluiile subproblemelor n soluia problemei originale, obinem recurena

    T(n) = (1) dac n c,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

    Notaia x desemneaz cel mai mic numr ntreg mai mare sau egal dect x i x desemneaz cel mai marenumr ntreg mai mic sau egal dect x. Aceste notaii sunt definite n capitolul 2.

  • 7/31/2019 Cormen - romaneste

    27/894

    1.3. Proiectarea algoritmilor 13

    problemei originale este o putere a lui 2. Fiecare pas de mprire genereaz deci dou subiruriavnd dimensiunea exact n/2. n capitolul 4 vom vedea c aceast presupunere nu afecteazordinul de cretere a soluiei recurenei.

    Pentru a determina recurena pentru T(n), timpul de execuie al sortrii prin interclasare an numere n cazul cel mai defavorabil, vom raiona n felul urmtor. Sortarea prin interclasare aunui singur element are nevoie de un timp constant. Cnd avem n > 1 elemente, vom descompunetimpul de execuie dup cum urmeaz:

    Divide: La acest pas, se calculeaz doar mijlocul subvectorului, calcul care are nevoie de untimp 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 elementeconsum (n) timp de execuie, deci C(n) = (n).

    Cnd adunm funciile D(n) i C(n) pentru analiza sortrii prin interclasare, adunm o funciecu timpul de execuie (n) cu o funcie cu timpul de execuie (1). Aceast sum este funcieliniar 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 pentrusortarea prin interclasare:

    T(n) =

    (1) dac n = 1,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 numeresuficient 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 pentruvectorul A = 3, 41, 52, 26, 38, 57, 9, 49.

    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, soluiarecurenei

    T(n) =

    2 dac n = 2,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 asorta A[1..n], sortm A[1..n 1] i apoi inserm A[n] n vectorul sortat A[1..n 1]. Scriei orecuren pentru timpul de execuie a acestei versiuni a sortrii prin inserie.

  • 7/31/2019 Cormen - romaneste

    28/894

    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 eliminadin 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 fieiterativ, fie recursiv, pentru cutarea binar. Argumentai c timpul de execuie n cazul cel maidefavorabil 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]. Putemutiliza n locul acesteia o cutare binar (vezi exerciiul 1.3-5), pentru a mbunti timpul deexecuie 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 omulime dat S de n numere reale i un alt numr real x, s decid dac printre elementele luiS 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 unminimum de efort. A folosi un algoritm nepotrivit pentru a rezolva o problem este ca i cums-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 calculatorpersonal i un supercalculator. De exemplu, s ne imaginm un supercalculator care ruleazsortarea prin inserie i un calculator personal care ruleaz sortarea prin interclasare. Fiecaretrebuie s sorteze un vector de un milion de numere. S presupunem c supercalculatorul poateexecuta 100 milioane de operaii pe secund, n timp ce calculatorul personal execut doarun milion de operaii pe secund. Pentru a face ca diferena s fie i mai dramatic, vompresupune c supercalculatorul utilizeaz pentru sortarea prin inserie un program executabilrealizat n cod main, optimizat de ctre cel mai bun programator, rezultatul fiind c suntnecesare 2n2 instruciuni la supercalculator pentru a realiza sortarea a n numere. Sortarea prininterclasare, 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 compilatorineficient, codului rezultat fiindu-i necesare 50n lg n instruciuni. Pentru a sorta un milion denumere, supercalculatorul are nevoie de

    2 (106)2 instruciuni108 instruciuni/secund

    = 20.000 secunde 5, 56 ore,

    n timp ce pentru calculatorul personal sunt necesare

    50 106 lg106 instruciuni106 instruciuni/secund

    1.000 secunde 16, 67 minute.

  • 7/31/2019 Cormen - romaneste

    29/894

    Probleme 15

    Prin utilizarea unui algoritm al crui timp de execuie are un ordin mai mic de cretere, chiar iun 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 algoritmiloreficieni, ct depinde de alegerea unui hardware rapid. Aa cum are loc o dezvoltare tehnologicrapid 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 sortriiprin 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 chiarmai 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 de100n2 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 x1, x2, . . . , xnconine cel puin doi termeni egali. Artai c acest fapt poate fi realizat n (n lg n), n carelg n reprezint log2 n.

    Probleme

    1-1 Comparaia timpilor de execuiePentru fiecare funcie f(n) i timp t din urmtorul tabel, determinai cea mai mare valoare a luin pentru o problem care poate fi rezolvat n timpul t, presupunnd c algoritmul de rezolvarea problemei are nevoie de f(n) microsecunde.

    1 1 1 1 1 1 1secund minut or zi lun an secol

    lg nn

    n

    n lg nn2

    n3

    2n

    n!

    1-2 Sortarea prin inserie pe vectori mici n sortarea prin interclasareDei timpul de execuie al algoritmului de sortare prin interclasare n cazul cel mai defavorabileste (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 pentruvalori mici ale lui n. Astfel, are sens s se utilizeze sortarea prin inserie n cadrul sortrii prin

  • 7/31/2019 Cormen - romaneste

    30/894

    16 Capitolul 1 Introducere

    interclasare, dac subproblemele devin suficient de mici. S considerm o modificare a sortriiprin interclasare n care n/k subvectori de lungine k sunt sortai utiliznd sortarea prin inseriei apoi interclasai folosind procedura standard de sortare prin interclasare, unde k este o valoarecare urmeaz a fi determinat.

    a. Artai c cei n/k subvectori, fiecare de lungime k, pot fi sortai prin inserie cu timp deexecuie (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 cazulcel mai defavorabil, care este cea mai mare valoare asimptotic a lui k (cu notaia ) nfuncie de n, pentru care algoritmul modificat are acelai timp de execuie ca i sortareastandard prin interclasare?

    d. Cum ar trebui ales k n mod practic?

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

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

    b. Ce vector avnd elemente din mulimea {1, 2, . . . , n} are cele mai multe inversiuni? Ct demulte?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 nelemente avnd timp de execuie (n lg n) n cazul cel mai defavorabil. ( Mo-dificai sortarea prin interclasare.)

    Note bibliografice

    Exist multe texte excelente n legtur cu subiectul general al algoritmilor, inclusiv celescrise 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 aleproiectrii algoritmilor sunt discutate de Bentley [24, 25] i Gonnet [90].

    n 1968, Knuth a publicat primul din cele trei volume cu titlul general[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 semnificativpentru multe din problematicile prezentate aici. Conform lui Knuth, cuvntul algoritm estederivat din numele al-Khowrizm, un matematician persan din secolul IX.

  • 7/31/2019 Cormen - romaneste

    31/894

    Note bibliografice 17

    Aho, Hopcroft i Ullman [4] au susinut analiza asimptotic a algoritmilor ca mijloc decomparare a performanei relative. Ei au popularizat utilizarea relaiilor de recuren pentru adescrie timpii de execuie ai algoritmilor recursivi.

    Knuth [123] prezint o tratare enciclopedic a multor algoritmi de sortare. Comparaiaalgoritmilor de sortare (capitolul 9) include analize exacte ale numrrii pailor, precum aceeacare am efectuat-o aici pentru sortarea prin inserie. Discuia lui Knuth despre sortarea prininserie 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 datelorde intrare pentru a produce un algoritm de sortare mai rapid.

    Sortarea prin interclasare este, de asemenea, descris de Knuth. Acesta menioneaz cJ. von Neumann a inventat n anul 1938 un mecanism capabil s interclaseze dou pachetede cartele perforate ntr-un singur pas. J. von Neumann, unul dintre pionierii informaticii, separe c a scris n 1945 un program pentru sortarea prin interclasare pe calculatorul EDVAC.

  • 7/31/2019 Cormen - romaneste

    32/894

    I Fundamente matematice

  • 7/31/2019 Cormen - romaneste

    33/894

    Introducere

    Analiza algoritmilor necesit deseori utilizarea uneltelor matematice. Aceste unelte uneorisunt foarte simple, cum ar fi algebra de liceu, dar altele, cum ar fi rezolvarea recurenelor s-arputea s reprezinte o noutate. Aceast parte a crii este un compendiu al metodelor i uneltelorpe 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 capitolelecare se ocup de algoritmi. Pe msur ce citii aceste capitole, revenii la aceast parte oricndavei 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, astfelnct s v formai fundamente matematice solide.

    Capitolul 2 definete riguros mai multe notaii asimptotice, de exemplu notaia folosit ncapitolul 1. n restul capitolului 2 sunt prezentate alte notaii matematice. Scopul este mai multde a asigura faptul c modul n care folosii notaiile matematice este acelai cu cel folosit ncarte, i nu de a v nva noi noiuni matematice.

    Capitolul 3 ofer metode pentru evaluarea i mrginirea sumelor, operaii ce apar foarte desn analiza algoritmilor.

    n capitolul 4 sunt prezentate metode de rezolvare a recurenelor, pe care le-am folosit, deexemplu, pentru a analiza sortarea prin interclasare n capitolul 1 i cu care ne vom ntlni demulte ori. O tehnic foarte eficient, care poate fi folosit pentru a rezolva recurene ce apar nalgoritmi divide i stpnete, este metoda master. O mare parte din capitolul 4 este alocat

    demonstrrii corectitudinii metodei master, dei cititorul poate sri peste aceast demonstraiefr 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 aistudiat anterior un curs de matematic discret.

    Capitolul 6 ncepe cu principii elementare de numrare: permutri, combinri i alte noiuniasemntoare. Restul capitolului conine definiii i proprieti elementare de probabilitate. Ceimai muli algoritmi din aceast carte nu necesit estimri probabilistice pentru analiza lor, deciputei omite cu uurin ultimele seciuni la o prim lectur, chiar fr a le rsfoi. Ulterior, cndvei ntlni o analiz probabilistic pe care dorii s o nelegei mai bine, vei constata c acestcapitol este bine organizat n acest sens.

  • 7/31/2019 Cormen - romaneste

    34/894

    2 Creterea funciilor

    Ordinul de cretere a timpului de execuie al unui algoritm, definit n capitolul 1 d ocaracterizare simpl pentru eficiena algoritmilor i ne d n acelai timp posibilitatea de acompara performanele relative ale unor algoritmi alternativi. De ndat ce dimensiunea n adatelor de intrare devine suficient de mare, algoritmul de sortare prin interclasare, cu timpul deexecuie (n l g 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 determinaexact timpul de execuie al unui algoritm, aa cum am fcut pentru sortarea prin inserie ncapitolul 1, n general, o precizie suplimentar nu merit efortul fcut. Pentru date de intraresuficient de mari, constantele multiplicative i termenii de ordin inferior din expresia exact aunui 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 ordinulde 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 algoritmo dat cu mrirea dimensiunii datelor de intrare, cnd dimensiunea datelor deintrare crete nemrginit. n mod uzual, un algoritm care este asimptotic mai eficient va fi ceamai 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 aalgoritmilor. 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 aparfrecvent n analiza algoritmilor.

    2.1. Notaia asimptotic

    Notaiile pe care le utilizm pentru a descrie timpul asimptotic de execuie al unui algoritmsunt 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 funciatimp de execuie n cazul cel mai defavorabil T(n) care n mod uzual este definit doar pentrudimensiuni ntregi ale datelor de intrare. Totui, este necesar uneori s folosim

    notaia asimptotic ntr-o varietate de moduri. De exemplu, notaia se extinde cu uurin ladomeniul 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 cndeste utilizat n mod abuziv s nu fie utilizat n mod . n aceast seciune se definescprincipalele notaii asimptotice i de asemenea, se introduc cteva abuzuri de notaie mai desntlnite.

    -notaia

    n capitolul 1 am artat c timpul de execuie pentru sortarea prin inserie n cazul cel maidefavorabil este T(n) = (n2). S definim acum exact aceast notaie. Pentru o funcie dat

  • 7/31/2019 Cormen - romaneste

    35/894

    2.1. Notaia asimptotic 21

    g(n), notm cu (g(n)),

    (g(n)) = { f(n) : exist constantele pozitive c1, c2 i n0 astfel nct0 c1g(n) f(n) c2g(n) pentru orice n n0}.

    O funcie f(n) aparine mulimii (g(n)) dac exist constantele pozitive c1 i c2 astfel nctaceasta s fie plasat ntre c1g(n) i c2g(n) pentru n suficient de mare. Dei (g(n)) este omulime, 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 poates 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 c1g(n)i mai mic sau egal cu c2g(n). Cu alte cuvinte, pentru orice n n0, s-ar putea spune cfuncia f(n) este egal cu g(n) pn la un factor constant. Vom spune c g(n) este o margineasimptotic 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 strictpozitiv pentru orice n suficient de mare. Prin urmare, funcia g(n) nsi ar trebui s fienenegativ, altfel mulimea (g(n)) este vid. Din acest motiv vom presupune n continuarec orice funcie utilizat n cadrul -notaiei este asimptotic nenegativ. Aceast presupunerermne valabil i pentru celelalte notaii asimptotice definite n acest capitol.

    n capitolul 1 am introdus o noiune neriguroas de -notaie care ducea la neglijareatermenilor 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 c12n2 3n = (n2). Pentru a face aceasta, trebuie determinate constantele pozitive c1, c2 i n0astfel nct

    c1n2 1

    2n2 3n c2n2

    pentru orice n n0. mprind cu n2, se obine

    c1 12

    3n

    c2.

    Inegalitatea din dreapta va fi verificat pentru orice n 1 dac al