this pageara/algoritmos-%20portugu%EAs-%20cormen.pdf

download this pageara/algoritmos-%20portugu%EAs-%20cormen.pdf

If you can't read please download the document

Transcript of this pageara/algoritmos-%20portugu%EAs-%20cormen.pdf

  • Teoria e Prt ica

  • Associao Brasileira para a Proteo dos Direitos

    Editoriais e Autorais

    Preencha a ficha de cadastro no final deste livro e receba gratuitamente informaes

    sobre os lanamentos e as promoes da Editora Campus.

    Consulte tambm nosso catlogo completo e ltimos lanamentos em

    www.campus.com.br

  • Fb, COR THd

    CHARLES E. L EISIFRSOM

    ROMALD L, WIVEST

    CL IFFORD STEIN

    Teor ia e P r t i c a

    J U S S A R A PIMENTA MATOS

    Dqartamento de Engenharia de Computao e Sistemas Digitais da Escola Politcnica da U S P

    e Consultora em Engenharia de Sofhoare

    T R A I

    VANDEN

    4" Tiragem

    - CAA

  • Do original Introduction to algorithms - Second Edition Traduo autorizada do idioma ingls da edio publicada por The MIT Press

    Copyright 2001 by The Massachusetts Institute of Technology

    O 2002, Elsevier Editora Ltda.

    Todos os direitos reservados e protegidos pela Lei 9.610 de 19/02/1998. Nenhuma parte deste livro, sem autorizao prvia por escrito da editora, poder ser reproduzida ou transmitida sejam quais forem os meios empregados: eletrnicos, mecnicos, fotogrficos, gravao ou quaisquer outros.

    Editorao Eletrnica Estdio Castellani

    Reviso Grfica Jane Castellani

    Projeto Grfico Elsevier Editora Ltda. A Qualidade da Informao. Rua Sete de Setembro, 11 1 - 16" andar 20050-006 Rio de Janeiro RJ Brasil Telefone: (21) 3970-9300 FAX: (21) 2507-1991 E-mail: info Oelsevier.com.br Escritrio So Paulo: Rua Elvira Ferraz. 198 04552-040 Vila Olmpia So Paulo SP Tel.: (1 1) 3841 -8555

    ISBN 85-352-0926-3 (Edio original: ISBN 0-07-01 31 51-1)

    CIP-Brasil. Catalogao-na-fonte. Sindicato Nacional dos Editores de Livros, RJ

    A385 Algoritmos : teoria e prtica 1 Thomas H. Cormen ... [et a[];

    traduo da segunda edio [americana] Vandenberg D. de Souza. - Rio de Janeiro : Elsevier, 2002 - @ Reimpresso.

    Traduo de: Introduction to algorithms ISBN 85-352-0926-3

    1. Programao (Computadores). 2. Algoritmos de computador. I. Cormen. Thomas H.

    O1 -1 674 CDD - 005.1 CDU - 004.421

    04 05 06 07 7 6 5 4

  • Sumrio

    Prefcio .......................................................... XI

    Parte i Fundamentos

    Introduo ........................................................ 1

    1 A funo dos algoritmos na computao . . . . . . . . . . . . . . . . . . . . . . . . . . . . - 3 1.1 Algoritmos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.2 Algoritmos como uma tecnologia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

    2 Conceitosbsicos .............................................. 11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1 Ordenao por insero 11

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Anlise de algoritmos 16

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3 Projeto de algoritmos 21

    ......................................... 3 Crescimentodefunes 32 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1 Notao assinttica 32

    3.2 Notaes padro e funes comuns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

    4 Xecorrncias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 4.1 O mtodo de substituio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 4.2 O mtodo de rvore de recurso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3 O mtodo mestre 59 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 4.4 Prova do teorema mestre 61

    5 Anlise probabistica e algoritmos aleatrios . . . . . . . . . . . . . . . . . . . . . . . . 73 5.1 O problema da contratao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 5.2 Indicadores de variveis aleatrias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 5.3 Algoritmos aleatrios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 5.4 Anlise probabilstica e usos adicionais de indicadores de variveis aleatrias . . 85

    Parte I1 Ordenao e estatsticas de ordem

    Introduo .................................................... 99

    6 Heapsort .................................................... 103 6.1 Heaps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 6.2 Manuteno da propriedade de heap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 6.3 A construo de um heap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 6.4 O algoritmo heapsort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 6.5 Filas de prioridades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111

    7 Quicksort .................................................... 117 7.1 Descrio do quicksort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 7.2 O desempenho de quicksort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 7.3 Uma verso aleatria de quicksort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 7.4 Anlise de quicksort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125

    I v

  • ..................................... 8 Ordenaoemtempoline ar 133 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.1 Limites inferiores para ordenao 133

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.2 Ordenao por contagem 135 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.3 Radixsort 137 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.4 Bucket sort 140

    ................................. 9 Medianas e estatsticas de ordem 147 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.1 Mnimo e mximo 147

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.2 Seleo em tempo esperado linear 149 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.3 Seleo em tempo linear no pior caso 152

    Parte I11 Estruturas de dados

    ...................................................... Introduo 159 ................................. 10 Estruturas de dados elementares 163

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.1 Pilhas e filas 163 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.2 Listas ligadas 166

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.3 Implementao de ponteiros e objetos 170 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.4 Representao de rvores enraizadas 173

    ................................................. 11 Tabelashash 179 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.1 Tabelas de endereo direto 179

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 Tabelashash 181

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.3 Funeshash 185 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.4 Endereamento aberto 192

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 11.5 Hash perfeito 198 ...................................... 12 rvores de pesquisa binria 204

    . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.1 O que uma rvore de pesquisa binria? 204 . . . . . . . . . . . . . . . . . . . . . . . 12.2 Consultas em uma rvore de pesquisa binria 207

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.3 Insero e eliminao 210 . . . . . . . . . . . . . . . . * 12.4 rvores de pesquisa binria construdas aleatoriamente 213

    ......................................... 13 rvores vermelho.preto 220 . . . . . . . . . . . . . . . . . . . . . . . . . . . 13.1 Propriedades de rvores vermelho-preto 220

    13.2 Rotaes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223 13.3 Insero . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13.4 Eliminao 231

    .................................. 14 Ampliando estruturas de dados 242 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14.1 Estatsticas de ordem dinmicas 242

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14.2 Como ampliar uma estrutura de dados 247 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14.3 rvores de intervalos 249

    Parte IV Tcnicas avanadas de projeto e anlise

    ...................................................... Introduo 257 ........................................ 15 Programao dinmica -259

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15.1 Programao de linha de montagem 260

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15.2 Multiplicao de cadeias de matrizes 266

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15.3 Elementos de programao dinmica 272 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15.3 Subsequncia comum mais longa 281

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15.5 rvores de pesquisa binria timas 285

  • ............................................ 16 Algoritmosgulosos 2 96 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16.1 Um problema de seleo de atividade 297

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16.2 Elementos da estratgia gulosa 303 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16.3 Cdigos de Huffman 307

    . . . . . . . . . . . . . . . . . . . . . . . . . + 16.4 Fundamentos tericos de mtodos gulosos 314 . . . . . . . . . . . . . . . . . . . . . . . . . . . + 16.5 Um problema de programao de tarefas 319

    ............................................ 17 Anliseamortizada 324 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17.1 A anlise agregada 325

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17.2 O mtodo de contabilidade 328 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17.3 O mtodo potencial 330

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17.4 Tabelas dinmicas 333

    Parte V Estruturas de dados avanadas

    Introduo ...................................................... 345 .................................................... 18 rvores B 349

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18.1 Definio de rvores B 352 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18.2 Operaes bsicas sobre rvores B 354

    . . . . . . . . . . . . . . . . . . . . . . . . . 18.3 Eliminao de uma chave de uma rvore B 360

    .............................................. 19 Heapsbinomiais 365 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19.1 rvores binomiais e heaps binomiais 366

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19.2 Operaes sobre heaps binomiais 370

    20 HeapsdeFibonacci ............................................ 381 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20.1 Estrutura de heaps de Fibonacci 382 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20.2 Operaes de heaps intercalveis 384

    . . . . . . . . . . . . . . . . . . . . . 20.3 Como decrementar uma chave e eliminar um n 390 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20.4 Como limitar o grau mximo 394

    ...................... 21 Estruturas de dados para conjuntos disjuntos - 3 9 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.1 Operaes de conjuntos disjuntos 398

    21.2 Representao de conjuntos disjuntos por listas ligadas . . . . . . . . . . . . . . . . . 400 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.3 Florestas de conjuntos disjuntos 403

    + 21.4 Anlise da unio por ordenao com compresso de caminho . . . . . . . . . . . . 406

    Parte VI Algoritmos de grafos

    ...................................................... Introduo 417 ................................ 22 Algoritmos elementares de grafos 419

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22.1 Representaes de grafos 419 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22.2 Pesquisa primeiro na extenso 422

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22.3 Pesquisa primeiro na profundidade 429 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22.4 Ordenao topolgica 436

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22.5 Componentes fortemente conectados 438

    .................................... 23 rvores de amplitude mnima 445 . . . . . . . . . . . . . . . . . . . 23.1 Como aumentar uma rvore de amplitude mnima 446

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23.2 Os algoritmos de Kruskal e Prim 450

    ............................ 24 Caminhos mais curtos de nica origem 459 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24.1 O algoritmo de Bellman-Ford 465 I "I1

  • 24.2 Caminhos mais curtos de nica origem em grafos acclicos orientados . . . . . 468 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24.3 Algoritmo de Dijkstra 470

    . . . . . . . . . . . . . . . . . . . . . 24.4 Restries de diferenas e caminhos mais curtos 475

    . . . . . . . . . . . . . . . . . . . . . 24.5 Provas de propriedades de caminhos mais curtos 480

    ........................... 25 Caminhos mais curtos de todos os pares 490 . . . . . . . . . . . . . . . . . . . . 25.1 Caminhos mais curtos e multiplicao de matrizes 492

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25.2 O algoritmo de Floyd.Warshal1 497 . . . . . . . . . . . . . . . . . . . . . . . . . 25.3 Algoritmo de Johnson para grafos esparsos 503

    26 Fluxomximo ................................................ 509 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26.1 Fluxo em redes 510

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26.2 O mtodo de Ford-Fulkerson 515 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26.3 Correspondncia bipartida mxima 525

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + 26.4 Algoritmos de push-relabel 529 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + 26.5 O algoritmo de relabel-to-front 538

    Parte VI1 Tpicos selecionados

    Introduo ...................................................... 553

    27 Redesdeordenao ........................................... 555 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27.1 Redes de comparao 555

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27.2 O princpio zero um 559 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27.3 Uma rede de ordenao bitnica 561

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27.4 Uma rede de intercalao 564 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27.5 Uma rede de ordenao 566

    ....................................... 28 Operaes sobre matllzes 571 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28.1 Propriedades de matrizes 571

    28.2 Algoritmo de Strassen para multiplicao de matrizes . . . . . . . . . . . . . . . . . 579 . . . . . . . . . . . . . . . . . . . . . . . . . 28.3 Resoluo de sistemas de equaes lineares 585

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28.4 Inverso de matrizes 597 28.5 Matrizes simtricas definidas como positivas e aproximao de mnimos

    quadrados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 601

    ............................................ 29 Programaolinear 610 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29.1 Formas padro e relaxada 616

    . . . . . . . . . . . . . . . . . . 29.2 Formulao de problemas como programas lineares 622 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29.3 O algoritmo simplex 626

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29.4 Dualidade 638 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29.5 A soluo bsica inicial possvel 643

    ............................................ 30 PolinmioseaFFT 651 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30.1 Representao de polinmios 653

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30.2 A D F T e a F F T 658 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30.3 Implementaes eficientes de FFT 664

    ................................ 31 Algoritmos de teoria dos nmeros 672 . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.1 Noes de teoria elementar dos nmeros 673

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.2 Mximo divisor comum 678 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.3 Aritmtica modular 682

    . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.4 Resoluo de equaes lineares modulares 688 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.5 O teorema chins do resto 691 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.6 Potncias de um elemento : . . . 693

  • . . . . . . . . . . . . . . . . . . . . . . 3 1.7 O sistema de criptografia de chave pblica RSA 697 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + 3 1.8 Como testar o carter primo 702

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + 3 1.9 Fatorao de inteiros 709 ..................................... 32 Correspondncia de cadeias 717

    . . . . . . . . . . . . . . . . . . . 32.1 O algoritmo simples de correspondncia de cadeias 719 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32.2 O algoritmo de Rabin.Karp 721

    . . . . . . . . . . . . . . . . . . . 32.3 Correspondncia de cadeias com autmatos finitos 725 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 32.4 O algoritmo de Knuth.Morris.Pratt 730

    ....................................... 33 Geometria compiitacional 7 3 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33.1 Propriedades de segmentos de linha 738

    33.2 Como determinar se dois segmentos quaisquer se cruzam . . . . . . . . . . . . . . 743 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33.3 Como encontrar a envoltria convexa 749

    . . . . . . . . . . . . . . . . . . . . . . . . 33.4 Localizao do par de pontos mais prximos 756

    ....................................... 34 Problemas NP-completos 763 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34.1 Tempo polinomial 767

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34.2 Verificao de tempo polinomial 773 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34.3 Carter NP-completo e redutibilidade 776

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34.4 Provas do carter NP.completo 785 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34.5 Problemas NP.completos 791

    ..................................... 35 Algoritmos de aproximao 806 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35.1 O problema de cobertura de vrtices 808

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35.2 O problema do caixeiro-viajante 810 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35.3 O problema de cobertura de conjuntos 815

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35.4 Aleatoriedade e programao linear 819 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35.5 O problema de soma de subconjuntos 823

    Parte VI11 Apndice: Fundamentos de matemtica

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduo 833

    ................................................... A Somatrios 835 . . . . . . . . . . . . . . . . . . . . . . . . . . . . A . l Frmulas e propriedades de somatrios 835

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A.2 Como limitar somatrios 838

    ....................................... B Conjuntos e outros temas 845 B.l Conjuntos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 845 B.2 Relaes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 849

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.3 Funes 851 B.4 Grafos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 853

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.5 rvores 856

    ...................................... C Contagem e probabilidade 863 C.l Contagem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 863

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C.2 Probabilidade 868 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C.3 Variveis aleatrias discretas 873

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . C.4 As distribuies geomtrica e binomial 878 . . . . . . . . . . . . . . . . . . . . . . . . . . + C.5 As extremidades da distribuio binomial 883

    Bibliografia ...................................................... 8 9 0

  • Prefcio

    Este livro oferece uma introduo abrangente ao estudo moderno de algoritmos de computa- dor. Ele apresenta muitos algoritmos e os examina com uma profundidade considervel, tor- nando seu projeto e sua anlise acessveis aos leitores de todos os nveis. Tentamos manter as explicaes em um nvel elementar sem sacrificar a profundidade do enfoque ou o rigor mate- mtico.

    Cada captulo apresenta um algoritmo, uma tcnica de projeto, uma rea de aplicao ou um tpico relacionado. Os algoritmos so descritos em linguagem comum e em um "pseudoc- digo" projetado para ser legvel por qualquer pessoa que tenha um pouco de experincia em programao. O livro contm mais de 230 figuras ilustrando como os algoritmos funcionam. Tendo em vista que enfatizamos a eficincia como um critrio de projeto, inclumos anlises cui- dadosas dos tempos de execuo de todos os nossos algoritmos. O texto foi planejado principalmente para uso em graduao e ps-graduao em algoritmos ou estruturas de dados. Pelo fato de discutir questes de engenharia relacionadas ao projeto de al- goritmos, bem como aspectos matemticos, o livro igualmente adequado para auto-estudo de profissionais tcnicos.

    Nesta segunda edio, atualizamos o livro inteiro. As mudanas variam da adio de novos captulos at a reestruturao de frases individuais.

    Para o professor

    Este livro foi projetado para ser ao mesmo tempo verstil e completo. Voc descobrir sua utilidade para uma variedade de cursos, desde a graduao em estruturas de dados, at a ps-graduao em algoritmos. Pelo fato de fornecermos uma quantidade de material conside- ravelmente maior do que poderia caber em um curso tpico de um perodo, voc deve imagi- nar o livro como um "buf" ou "depsito", do qual pode selecionar e extrair o material que me- lhor atender ao curso que desejar ministrar.

    Voc achar fcil organizar seu curso apenas em torno dos captulos de que necessitar. Tor- namos os captulos relativamente autnomos, para que voc no precise se preocupar com uma dependncia inesperada e desnecessria de um captulo em relao a outro. Cada captulo apre- senta primeiro o material mais fcil e mostra os assuntos mais difceis em seguida, com limites de sees assinalando pontos de parada naturais. Na graduao, podero ser utilizadas apenas as primeiras sees de um captulo; na ps-graduao, ser possvel estudar o captulo inteiro.

    Inclumos mais de 920 exerccios e mais de 140 problemas. Cada seo termina com exerc- cios, e cada captulo com problemas. Em geral, os exerccios so perguntas curtas que testam o domnio bsico do assunto. Alguns so exerccios simples criados para a sala de aula, enquanto outros so mais substanciais e apropriados para uso como dever de casa. Os problemas so estu- dos de casos mais elaborados que, com frequncia, apresentam novos assuntos; normalmente, eles consistem em vrias perguntas que conduzem o aluno por etapas exigidas para chegar a uma soluo.

    Assinalamos com asteriscos (*) as sees e os exerccios mais adequados para alunos avana- dos. Uma seo com asteriscos no necessariamente mais difcil que outra que no tenha aste- riscos, mas pode exigir a compreenso de matemtica em um nvel mais profundo. Da mesma forma, os exerccios com asteriscos podem exigir um conhecimento mais avanado ou criativi- dade acima da mdia. I XI

  • Para o aluno

    Esperamos que este livro-texto lhe proporcione uma introduo agradvel ao campo dos algo- ritmos. Tentamos tornar cada algoritmo acessvel e interessante. Para ajud-lo quando voc en- contrar algoritmos pouco familiares ou difceis, descrevemos cada um deles passo a passo. Tam- bm apresentamos explicaes cuidadosas dos conhecimentos matemticos necessrios a com- preenso da anlise dos algoritmos. Se j tiver alguma familiaridade com um tpico, voc perce- ber que os captulos esto organizados de modo que seja possvel passar os olhos pelas sees introdutrias e seguir rapidamente para o material mais avanado.

    Este um livro extenso, e sua turma provavelmente s examinar uma parte de seu conte- do. Porm, procuramos torn-lo til para voc agora como um livro-texto, e tambm mais tar- de em sua carreira, sob a forma de um guia de referncia de matemtica ou um manual de en- genharia.

    Quais so os pr-requisitos para a leitura deste livro?

    O Voc deve ter alguma experincia em programao. Em particular, deve entender proce- dimentos recursivos e estruturas de dados simples como arranjos e listas ligadas.

    O Voc deve ter alguma facilidade com a realizao de demonstraes por induo matem- tica. Algumas panes do livro se baseiam no conhecimento de clculo elementar. Alm dis- so, as Partes I e VI11 deste livro ensinam todas as tcnicas matemticas de que voc ir ne- cessitar.

    Para o profissional

    A ampla variedade de tpicos deste livro o torna um excelente manual sobre algoritmos. Como cada captulo relativamente autnomo, voc pode se concentrar nos tpicos que mais o inte- ressem.

    A maioria dos algoritmos que discutimos tem grande utilidade prtica. Por essa razo, abor- damos conceitos de implementao e outras questes de engenharia. Em geral, oferecemos al- ternativas prticas para os poucos algoritmos que tm interesse principalmente terico.

    Se desejar implementar algum dos algoritmos, voc ir achar a traduo do nosso pseudoc- digo em sua linguagem de programao favorita uma tarefa bastante objetiva. O pseudocdigo foi criado para apresentar cada algoritmo de forma clara e sucinta. Conseqentemente, no nos preocupamos com o tratamento de erros e outras questes ligadas a engenharia de software que exigem suposies especficas sobre o seu ambiente de programao. Tentamos apresentar cada algoritmo de modo simples e direto sem permitir que as idiossincrasias de uma determina- da linguagem de programao obscurecessem sua essncia.

    Para os nossos colegas

    Fornecemos uma bibliografia e ponteiros extensivos para a literatura corrente. Cada captulo termina com um conjunto de "notas do captulo" que fornecem detalhes e referncias histri- cas. Contudo, as notas dos captulos no oferecem uma referncia completa para o campo intei- ro de algoritmos. Porm, pode ser difcil acreditar que, em um livro com este tamanho, mui'tos algoritmos interessantes no puderam ser includos por falta de espao.

    Apesar dos inmeros pedidos de solues para problemas e exerccios feitos pelos alunos, escolhemos como norma no fornecer referncias para problemas e exerccios, a fim de evitar que os alunos cedessem a tentao de olhar uma soluo pronta em lugar de encontr-la eles mesmos.

  • Mudanas na segunda edio

    O que mudou entre a primeira e a segunda edio deste livro? Dependendo de como voc o encara, o livro pode no ter mudado muito ou ter mudado

    bastante. Um rpido exame no sumrio mostra que a maior parte dos captulos e das sees da primei-

    ra edio tambm esto presentes na segunda edio. Removemos dois captulos e algumas se- es, mas adicionamos trs novos captulos e quatro novas sees alm desses novos captulos. Se fosse julgar o escopo das mudanas pelo sumrio, voc provavelmente concluiria que as mu- danas foram modestas.

    Porm, as alteraes vo muito alm do que aparece no sumrio. Sem qualquer ordem parti- cular, aqui est um resumo das mudanas mais significativas da segunda edio:

    s Cliff Stein foi includo como co-autor

    s Os erros foram corrigidos. Quantos erros? Vamos dizer apenas que foram vrios.

    H trs novos captulos:

    O Captulo 1 discute a funo dos algoritmos em informtica.

    O Captulo 5 abrange a anlise probabilstica e os algoritmos aleatrios. Como na pri- meira edio, esses tpicos aparecem em todo o livro.

    s O Captulo 29 dedicado programao linear.

    Dentro dos captulos que foram trazidos da primeira edio, existem novas sees sobre os seguintes tpicos:

    Hash perfeito (Seo 11.5).

    Duas aplicaes de programao dinmica (Sees 15.1 e 15.5).

    Aigoritmos de aproximao que usam tcnicas aleatrias e programao linear (Seo 35.4).

    s Para permitir que mais algoritmos apaream mais cedo no livro, trs dos captulos sobre fundamentos matemticos foram reposicionados, migrando da Parte I para os apndices, que formam a Parte VIII.

    s H mais de 40 problemas novos e mais de 185 exerccios novos.

    Tornamos explcito o uso de loops invariantes para demonstrar a correo. Nosso pri- meiro loop invariante aparece no Captulo 2, e ns os utilizamos algumas dezenas de ve- zes ao longo do livro.

    s Muitas das anlises probabilsticas foram reescritas. Em particular, usamos em aproximada- mente uma dezena de lugares a tcnica de "variveis indicadoras aleatrias" que simplificam as anlises probabilsticas, em especial quando as variveis aleatrias so dependentes.

    Expandimos e atualizamos as notas dos captulos e a bibliogr&a. A bibliografia cresceu mais de 50%, e mencionamos muitos novos resultados algortmicos que surgiram aps a impresso da primeira edio.

    Tambm faemos as seguintes mudanas:

    O captulo sobre resoluo de recorrncias no contm mais o mtodo de iterao. Em vez disso, na Seo 4.2, "promovemos" as rvores de recurso, que passaram a constituir um mtodo por si s. Conclumos que criar rvores de recurso menos propenso a er- ros do que fazer a iterao de recorrncias. Porm, devemos assinalar que as rvores de recurso so mais bem usadas como um modo de gerar hipteses que sero ento verifi- cadas atravs do mtodo de substituio. I XIII

  • O mtodo de particionamento usado para ordenao rpida (Seo 7.1) e no algoritmo de ordem estatstica de tempo linear esperado (Seo 9.2) diferente. Agora usamos o mtodo desenvolvido por Lomuto que, junto com variveis indicadoras aleatrias, per- mite uma anlise um pouco mais simples. O mtodo da primeira edio, devido a Hoare, apresentado como um problema no Captulo 7.

    Modificamos a discusso sobre o hash universal da Seo 11 3 .3 de forma que ela se inte- gre a apresentao do hash perfeito.

    Voc encontrar na Seo 12.4 uma anlise muito mais simples da altura de uma rvore de pesquisa binria construda aleatoriamente.

    As discusses sobre os elementos de programao dinmica (Seo 15.3) e os elementos de algoritmos gulosos (Seo 16.2) foram significativamente expandidas. A explorao do problema de seleo de atividade, que inicia o captulo de algoritmos gulosos, ajuda a esclarecer a relao entre programao dinmica e algoritmos gulosos.

    Substitumos a prova do tempo de execuo da estrutura de dados de unio de conjuntos disjuntos na Seo 2 1.4 por uma prova que emprega o mtodo potencial para derivar um limite restrito.

    A prova de correo do algoritmo para componentes fortemente conectados na Seo 22.5 mais simples, mais clara e mais direta.

    O Captulo 24, que aborda os caminhos mais curtos de origem nica, foi reorganizado com a finalidade de mover as provas das propriedades essenciais para suas prprias se- es. A nova organizao permite que nos concentremos mais cedo nos algoritmos.

    A Seo 34.5 contm uma viso geral ampliada do carter NP-completo, e tambm novas provas de carter NP-completo para os problemas do ciclo hamiltoniano e da soma de subconjuntos.

    Por fim, virtualmente todas as sees foram editadas para corrigir, simplificar e tornar mais claras as explicaes e demonstraes.

    Agradecimentos da primeira edio

    Muitos amigos e colegas contriburam bastante para a qualidade deste livro. Agradecemos a to- dos por sua ajuda e suas crticas construtivas.

    O laboratrio de cincia da computao do MIT proporcionou um ambiente de trabalho ideal. Nossos colegas do grupo de teoria da computao do laboratrio foram particularmente incenti- vadores e tolerantes em relao aos nossos pedidos incessantes de avaliao crtica dos captulos. Agradecemos especificamente a Baruch Awerbuch, Shafi Goldwasser, Leo Guibas, Tom Leighton, Albert Meyer, David Shmoys e va Tardos. Agradecemos a William Ang, Sally Bemus, Ray Hirschfeld e Mark Reinhold por manterem nossas mquinas (equipamentos DEC Microvax, Apple Macintosh e Sun Sparcstation) funcionando e por recompilarem TEX sempre que excedemos um limite de prazo de compilao. A Thinking Machines Corporation forneceu suporte parcial a Char- les Leiserson para trabalhar neste livro durante um perodo de ausncia do MIT.

    Muitos colegas usaram rascunhos deste texto em cursos realizados em outras faculdades. Eles sugeriram numerosas correes e revises. Desejamos agradecer em particular a Richard Beigel, Andrew Goldberg, Joan Lucas, Mark Overmars, Alan Sherman e Diane Souvaine.

    Muitos assistentes de ensino em nossos cursos apresentaram contribuies significativas para o desenvolvimento deste material. Agradecemos especialmente a Alan Baratz, Bonnie Ber- ger, Aditi Dhagat, Burt Kaliski, Arthur Lent, Andrew Moulton, Marios Papaefthyrniou, Cindy Phil- lips, Mark Reinhold, Phil Rogaway, Flavio Rose, Arie Rudich, Alan Sherman, Cliff Stein, Susmita

    xivl Sur, Gregory Troxel e Margaret Tuttle.

  • Uma valiosa assistncia tcnica adicional foi fornecida por muitas pessoas. Denise Sergent passou muitas horas nas bibliotecas do MIT pesquisando referncias b i b l i ~ g r ~ c a s . Maria Sensa- le, a bibliotecria de nossa sala de leitura, foi sempre atenciosa e alegre. O acesso a biblioteca pessoal de Albert Meyer nos poupou muitas horas na biblioteca durante a preparao das anota- es dos captulos. Shlomo Kipnis, Bill Niehaus e David Wilson revisaram os exerccios antigos, desenvolveram novos e escreveram notas sobre suas solues. Marios Papaefthymiou e Gregory Troxel contriburam para a indexao. Ao longo dos anos, nossas secretrias Inna Radzihovsky, Denise Sergent, Gayle Sherman e especialmente Be Blackburn proporcionaram apoio infind- vel a este projeto, e por isso somos gratos a elas.

    Muitos erros nos rascunhos iniciais foram relatados por alunos. Agradecemos especifica- mente a Bobby Blumofe, Bonnie Eisenberg, Rayrnond Johnson, John Keen, Richard Lethin, Mark Lillibridge, John Pezaris, Steve Ponzio e Margaret Tuttle por sua leitura cuidadosa dos ori- ginais.

    Nossos colegas tambm apresentaram resenhas crticas de captulos especficos, ou infor- maes sobre determinados algoritmos, pelos quais somos gratos. Agradecemos ainda a Bill Aiello, Alok Aggarwal, Eric Bach, VaSek Chvtal, Richard Cole, Johan Hastad, Alex Ishii, David Johnson, Joe Kilian, Dina Kravets, Bruce Maggs, Jim Orlin, James Park, Thane Plambeck, Hers- chel Safer, Jeff Shallit, Cliff Stein, Gil Strang, Bob Tarjan e Paul Wang. Vrios de nossos colegas gentilmente tambm nos forneceram problemas; agradecemos em particular a Andrew Gold- berg, Danny Sleator e Umesh Vazirani.

    Foi um prazer trabalhar com The MIT Press e a McGraw-Hill no desenvolvimento deste tex- to. Agradecemos especialmente a Frank Satlow, Terry Ehling, Larry Cohen e Lorrie Lejeune da The MIT Press, e a David Shapiro da McGraw-Hill por seu encorajamento, apoio e pacincia. So- mos particularmente agradecidos a Larry Cohen por seu excelente trabalho de edio.

    Agradecimentos da segunda edio

    Quando pedimos a Julie Sussman, P. P. A., que atuasse como editora tcnica da segunda edio, no sabamos que bom negcio estvamos fazendo. Alm de realizar a edio do contedo tc- nico, Julie editou entusiasticamente nosso texto. humilhante pensar em quantos erros Julie encontrou em nossos esboos antigos; entretanto, considerando a quantidade de erros que ela achou na primeira edio (depois de impressa, infelizmente), isso no surpreende. Alm disso, Julie sacrificou sua prpria programao para se adaptar a nossa - chegou at a levar captulos do livro com ela em uma viagem as Ilhas Virgens! Julie, nunca conseguiremos agradecer-lhe o bastante pelo trabalho fantstico que voc realizou.

    O trabalho para a segunda edio foi feito enquanto os autores eram membros do departa- mento de cincia da computao no Dartmouth College e no laboratrio de cincia da computa- o do MIT. Ambos foram ambientes de trabalho estimulantes, e agradecemos a nossos colegas por seu apoio.

    Amigos e colegas do mundo inteiro ofereceram sugestes e opinies que orientaram nossa escrita. Muito obrigado a Sanjeev Arora, Javed Aslam, Guy Blelloch, Avrim Blum, Scot Drysdale, Hany Farid, Hal Gabow, Andrew Goldberg, David Johnson, Yanlin Liu, Nicolas Schabanel, Ale- xander Schrijver, Sasha Shen, David Shmoys, Dan Spielman, Gerald Jay Sussman, Bob Tarjan, Mikkel Thorup e Vijay Vazirani.

    Vrios professores e colegas nos ensinaram muito sobre algoritmos. Em particular, reconhe- cemos o esforo e a dedicao de nossos professores Jon L. Bentley, Bob Floyd, Don Knuth, Ha- rold Kuhn, H. T. Kung, Richard Lipton, Arnold Ross, Larry Snyder, Michael I. Shamos, David Shmoys, Ken Steiglitz, Tom Szymanski, va Tardos, Bob Tarjan e Jeffrey Ullman.

    Reconhecemos o trabalho dos muitos assistentes de ensino dos cursos de algoritmos no MIT e em Dartmouth, inclusive Joseph Adler, Craig Barrack, Bobby Blumofe, Roberto De Prisco, Mat- teo Frigo, Igal Galperin, David Gupta, Raj D. Iyer, Nabil Kahale, Sarfraz Khurshid, Stavros Kollio- poulos, Alain Leblanc, Yuan Ma, Maria Minkoff, Dimitris Mitsouras, Alin Popescu, Harald Pro- l

  • kop, Sudipta Sengupta, Donna Slonim, Joshua A. Tauber, Sivan Toledo, Elisheva Werner-Reiss, Lea Wittie, Qiang Wu e Michael Zhang.

    O suporte de informtica foi oferecido por William Ang, Scott Blomquist e Greg Shomo no MIT e por Wayne Cripps, John Konkle e Tim Tregubov em Dartmouth. Agradecemos tambm a Be Blackburn, Don Dailey, Leigh Deacon, Irene Sebeda e Cheryl Patton Wu no MIT, e a Phyllis Bellmore, Kelly Clark, Delia Mauceli, Sammie Travis, Deb Whiting e Beth Young, de Dartmouth, pelo suporte administrativo. Michael Fromberger, Brian Campbell, Arnanda Eubanks, Sung Hoon Kim e Neha Narula tambm ofereceram apoio oportuno em Dartmouth.

    Muitas pessoas fizeram a gentileza de informar sobre erros cometidos na primeira edio. Agradecemos aos leitores mencionados na lista a seguir; cada um deles foi o primeiro a relatar um erro da primeira edio: Len Adleman, Selim Akl, Richard Anderson, Juan Andrade-Cetto, Gregory Bachelis, David Barrington, Paul Beame, Richard Beigel, Margrit Betke, Alex Blakemo- re, Bobby Blumofe, Aiexarider Brown, Xavier Cazin, Jack Chan, Richard Chang, Chienhua Chen, Ien Cheng, Hoon Choi, Dme Coles, Christian Collberg, George Collins, Eric Conrad, Peter Csas- zar, Paul Dietz, Martin Dietzfelbinger, Scot Drysdale, Patricia Ealy, Yaakov Eisenberg, Michael Ernst, Michael Formann, Nedim Fresko, Hal Gabow, Marek Galecki, Igal Galperin, Luisa Garga- no, John Gately, Rosario Genario, Mihaly Gereb, Ronald Greenberg, Jerry Grossman, Stephen Guattery, Alexander Hartemik, Anthony Hill, Thomas Hofrneister, Mathew Hostetter, Yih-Chun Hu, Dick Johnsonbaugh, Marcin Jurdzinki, Nabil Kahale, Fumiaki Kamiya, Anand Kanagala, Mark Kantrowitz, Scott Karlin, Dean Kelley, Sanjay Khanna, Haluk Konuk, Dina Kravets, Jon Kro- ger, Bradley Kuszmaul, Tim Lambert, Hang Lau, Thomas Lengauer, George Madrid, Bruce Maggs, Victor Miller, Joseph Muskat, Tung Nguyen, Michael Orlov, James Park, Seongbin Park, Ioannis Paschalidis, Boaz Patt-Shamir, Leonid Peshkin, Patricio Poblete, Ira Pohl, Stephen Pon- zio, Kjell Post, Todd Poynor, Colin Prepscius, Sholom Rosen, Dale Russell, Hershel Safer, Karen Seidel, Joel Seiferas, Erik Seligman, Stanley Selkow, Jeffrey Shallit, Greg Shannon, Micha Sharir, Sasha Shen, Norman Shulman, Andrew Singer, Daniel Sleator, Bob Sloan, Michael Sofka, Volker Strumpen, Lon Sunshine, Julie Sussman, Asterio Tanaka, Clark Thomborson, Nils Thommesen, Homer Tilton, Martin Tompa, Andrei Toom, Felzer Torsten, Hirendu Vaishnav, M. Veldhorst, Luca Venuti, Jian Wang, Michael Wellman, Gerry Wiener, Ronald Williams, David Wolfe, Jeff Wong, Richard Woundy, Neal Young, Huaiyuan Yu, Tian Yuxing, Joe Zachary, Steve Zhang, Flo- rian Zschoke e Uri Zwick.

    Muitos de nossos colegas apresentaram crticas atentas ou preencheram um longo formulrio de pesquisa. Agradecemos aos revisores Nancy Amato, Jim Aspnes, Kevin Compton, Wiiliam Evans, Peter Gacs, Michael Goldwasser, Andrzej Proskurowski, Vijaya Rarnachandran e John Reif. Tambm agradecemos s seguintes pessoas por devolverem a pesquisa: James Abello, Josh Benaloh, Bryan Beresford-Smith, Kenneth Blaha, Hans Bodlaender, Richard Borie, Ted Brown, Domenico Cantone, M. Chen, Robert Cimikowski, WUam Clocksin, Paul Culi, Rick Decker, Matthew Dickerson, Robert Douglas, Margaret Fleck, Michael Goodrich, Susanne Harnbrusch, Dean Hendrix, Richard Johnson- baugh, Kyriakos Kalorkoti, Srinivas Kankanahalli, Hikyoo Koh, Steven Lindell, Erro1 Lloyd, Andy Lo- pez, Dian Rae Lopez, George Lucker, David Maier, Charles Martel, Xiannong Meng, David Mount, Alberto Policriti, Andrzej Proskurowski, Kirk Pruhs, Yves Robert, Guna Seetharaman, Stanley Sel- kow, Robert Sloan, Charles Steele, Gerard Tel, Murali Varanasi, Bernd Walter e Alden Wright. Gosta- ramos que tivesse sido possvel implementar todas as suas sugestes. O nico problema que, se isso fosse feito, a segunda edio teria mais ou menos 3.000 pginas!

    A segunda edio foi produzida em I&T#2,. Michael Downes converteu as macros de I&T$ do I&T$ "clssico" para I&T$2, e converteu os arquivos de texto para usar essas novas macros. David Jones tambm forneceu suporte para h'T52,. As figuras da segunda edio foram produ- zidas pelos autores usando o MacDraw Pro. Como na primeira edio, o ndice foi compilado com o uso de Windex, um programa em C escrito pelos autores, e a bibliografia foi preparada com a utilizao do BIBTS Ayorkor Mills-Tettey e Rob Leathern ajudaram a converter as figuras para MacDraw Pro, e Ayorkor tambm conferiu nossa bibliografia.

  • Como tambm aconteceu na primeira edio, trabalhar com The MIT Press e com a McGraw- Hili foi um prazer. Nossos editores, Bob Prior da MIT Press e Betsy Jones da McGraw-Hill, tolera- ram nossos gracejos e nos mantiveram no rumo.

    Finalmente, agradecemos a nossas esposas - Nicole Cormen, Gail Rivest e Rebecca Ivry - a nossos filhos - Ricky, William e Debby Leiserson, Alex e Christopher Rivest, e Molly, Noah e Ben- jamin Stein - e a nossos pais - Renee e Perry Cormen, Jean e Mark Leiserson, Shirley e Lloyd Ri- vest, e Irene e Ira Stein - por seu carinho e apoio durante a elaborao deste livro. O amor, a pa- cincia e o incentivo de nossos familiares tornaram este projeto possvel. Dedicamos afetuosa- mente este livro a eles.

    Thomas H. Cormen Charles E. Leiserson Ronald L. Rivest Clifford Stein

    Hanouer, New Hampshire Cambridge, Massachusetts Cambridge, Massachusetts Hanover, New Hampshire

    Maio de 2001

  • Par te I

    Fundamentos

    Introduqo Esta parte o far refletir sobre o projeto e a anlise de algoritmos. Ela foi planejada para ser uma introduo suave ao modo como especificamos algoritmos, a algumas das estratgias de projeto que usaremos ao longo deste livro e a muitas das idias fundamentais empregadas na anlise de algoritmos. As partes posteriores deste livro sero elaboradas sobre essa base.

    O Captulo 1 uma viso geral dos algoritmos e de seu lugar nos modernos sistemas de com- putao. Esse captulo define o que um algoritmo e lista alguns exemplos. Ele tambm apre- senta os algoritmos como uma tecnologia, da mesma maneira que um hardware rpido, interfa- ces grficas do usurio, sistemas orientados a objetos e redes de computadores.

    No Captulo 2, veremos nossos primeiros algoritmos, que resolvem o problema de ordenar uma sequncia de n nmeros. Eles so escritos em um pseudocdigo que, embora no possa ser traduzido diretamente para qualquer linguagem de programao convencional, transmite a es- trutura do algoritmo com clareza suficiente para que um programador competente possa imple- ment-Ia na linguagem de sua escolha. Os algoritmos de ordenao que examinaremos so a or- denao por insero, que utiliza uma abordagem incremental, e a ordenao por intercalao, que usa uma tcnica recursiva conhecida como "dividir e conquistar". Embora o tempo exigido por cada uma aumente com o valor n, a taxa de aumento difere entre os dois algoritmos. Deter- minaremos esses tempos de execuo no Captulo 2 e desenvolveremos uma notao til para express-los.

    O Captulo 3 define com exatido essa notao, que chamaremos notao assinttica. Ele come- a definindo diversas notaes assintticas que utilizaremos para delimitar os tempos de execuo dos algoritmos acima e/ou abaixo. O restante do Captulo 3 principalmente uma apresentao da notao matemtica. Seu propsito maior o de assegurar que o uso que voc far da notao cor- responder a utilizao deste livro, em vez de ensinar-lhe novos conceitos matemticos.

    O Captulo 4 mergulha mais profundamente no mtodo de dividir e conquistar introduzido no Captulo 2. Em particular, o Captulo 4 contm mtodos para soluo de recorrncias que so teis para descrever os tempos de execuo de algoritmos recursivos. Uma tcnica eficiente o "mtodo mestre", que pode ser usado para resolver recorrncias que surgem dos algoritmos de dividir e conquistar. Grande parte do Captulo 4 dedicada a demonstrar a correo do m- todo mestre, embora essa demonstrao possa ser ignorada sem problemas. I ]

  • O Captulo 5 introduz a anlise probabilstica e os algoritmos aleatrios. Em geral, usaremos a anlise probabilstica para determinar o tempo de execuo de um algoritmo nos casos em que, devido a presena de uma distribuio de probabilidades inerente, o tempo de execuo pode diferir em diversas entradas do mesmo tamanho. Em alguns casos, vamos supor que as en- tradas obedecem a uma distribuio de probabilidades conhecida, e assim calcularemos o tem- po de execuo mdio sobre todas as entradas possveis. Em outros casos, a distribuio de pro- babilidades no vem das entradas, mas sim das escolhas aleatrias feitas durante o curso do algo- ritmo. Um algoritmo cujo comportamento determinado no apenas por sua entrada, mas tambm pelos valores produzidos por um gerador de nmeros aleatrios, um algoritmo alea- trio. Podemos usar algoritmos aleatrios para impor uma distribuio de probabilidade sobre as entradas - assegurando assim que nenhuma entrada especfica sempre causar um fraco de- sempenho - ou mesmo para limitar a taxa de erros de algoritmos que tm permisso para pro- duzir resultados incorretos de forma limitada.

    Os Apndices A, B e C contm outros materiais matemticos que voc ir considerar teis a medida que ler este livro. provvel que voc tenha visto grande parte do material dos apndi- ces antes de encontr-los neste livro (embora as convenes especficas de notao que usamos possam diferir em alguns casos daquelas que voc j viu), e assim voc deve considerar os apn- dices um guia de referncia. Por outro lado, provvel que voc ainda no tenha visto a maior parte do material contido na Parte I. Todos os captulos da Parte I e os apndices foram escritos com um "toque" de tutorial.

  • Capitulo I

    A funo dos algoritmos na computao

    O que so algoritmos? Por que o estudo dos algoritmos vale a pena? Qual a funo dos aigorit- mos em relao a outras tecnologias usadas em computadores? Neste captulo, responderemos a essas perguntas.

    1.1 Algoritmos Informalmente, um algo1-t:tmo qualquer procedimento computacionai bem definido que toma algum valor ou conjunto de valores como entrada e produz algum valor ou conjunto de valores como sada. Portanto, um algoritmo uma sequncia de passos computacionais que transformam a entrada na sada.

    Tambm podemos visualizar um aigoritmo como uma ferramenta para resolver umproble- ma computacional bem especificado. O enunciado do problema especifica em termos gerais o relacionamento entre a entrada e a saida desejada. O algoritmo descreve um procedimento computacional especfico para se alcanar esse relacionamento da entrada com a sada.

    Por exemplo, poderia ser necessrio ordenar uma sequncia de nmeros em ordem no de- crescente. Esse problema surge com frequncia na prtica e oferece um solo frtil para a intro- duo de muitas tcnicas de projeto padro e ferramentas de anlise. Vejamos como definir for- malmente o problema de ordenao:

    Entrada: Uma sequncia de n nmeros (a,, a*, ..., a,).

    Sada: Uma permutao (reordenao) (a;, a;, . . . , al, ) da sequncia de entrada, tal que ai I ai I ... Ia:.

    Dada uma sequncia de entrada como (3 1,4 1,59,26,4 1,58), um algoritmo de ordenao re- torna como sada a sequncia (26,31,41,41,58,59). Uma sequncia de entrada como essa cha- mada uma instncia do problema de ordenao. Em geral, uma instncia de um problema consiste na entrada (que satisfaz a quaisquer restries impostas no enunciado do problema) necessria para se calcular uma soluo para o problema.

    A ordenao uma operao fundamental em cincia da computao (muitos programas a utilizam como uma etapa intermediria) e, como resultado, um grande nmero de bons algorit- mos de ordenao tem sido desenvolvido. O melhor aigoritmo para uma determinada aplicao

    13

  • depende -entre outros fatores - do nmero de itens a serem ordenados, da extenso em que os itens j esto ordenados de algum modo, de possveis restries sobre os valores de itens e da es- pcie de dispositivo de armazenamento a ser usado: memria principal, discos ou fitas.

    Um algoritmo dito cometo se, para cada instncia de entrada, ele pra com a sada correta. Dizemos que um algoritmo correto resolve o problema computacional dado. Um algoritmo in- correto pode no parar em algumas instncias de entrada, ou ento pode parar com outra res- posta que no a desejada. Ao contrrio do que se poderia esperar, as vezes os algoritmos incor- retos podem ser teis, se sua taxa de erros pode ser controlada. Veremos um exemplo desse fato no Captulo 3 1, quando estudarmos algoritmos para localizar grandes nmeros primos. Porm, em situaes comuns, iremos nos concentrar apenas no estudo de algoritmos corretos.

    Um algoritmo pode ser especificado em linguagem comum, como um programa de compu- tador, ou mesmo como um projeto de hardware. O nico requisito que a especificao deve fornecer uma descrio precisa do procedimento computacional a ser seguido.

    Que tipos de problemas so resolvidos por algoritmos?

    A ordenao no de modo algum o nico problema computacional para o qual foram desenvolvidos algoritmos. (Voc provavelmente suspeitou disso quando viu o tamanho deste livro.) As aplicaes prticas de algoritmos so onipresentes e incluem os exemplos a seguir:

    O Projeto Genoma Humano tem como objetivos identificar todos os 100.000 genes do DNA humano, determinar as sequncias dos 3 bilhes de pares de bases qumicas que constituem o DNA humano, armazenar essas informaes em bancos de dados e desen- volver ferramentas para anlise de dados. Cada uma dessas etapas exige algoritmos sofis- ticados. Embora as solues para os vrios problemas envolvidos estejam alm do escopo deste livro, idias de muitos captulos do livro so usadas na soluo desses problemas bio- lgicos, permitindo assim aos cientistas realizarem tarefas ao mesmo tempo que utilizam com eficincia os recursos. As economias so de tempo, tanto humano quanto da mqui- na, e de dinheiro, a medida que mais informaes podem ser extradas de tcnicas de la- boratrio.

    A Internet permite que pessoas espalhadas por todo o mundo acessem e obtenham com rapidez grandes quantidades de informaes. Para isso, so empregados algoritmos inteligentes com a finalidade de gerenciar e manipular esse grande volume de dados. Os exemplos de problemas que devem ser resolvidos incluem a localizao de boas rotas pelas quais os dados viajaro (as tcnicas para resolver tais problemas so apresentadas no Captulo 24) e o uso de um mecanismo de pesquisa para encontrar com rapidez pginas em que residem informaes especficas (as tcnicas relacionadas esto nos Captulos 11 e 32).

    O comrcio eletrnico permite que mercadorias e servios sejam negociados e trocados eletronicamente. A capacidade de manter privativas informaes como nmeros de carto de crdito, senhas e extratos bancrios essencial para a ampla utilizao do comrcio eletrnico. A criptografia de chave pblica e as assinaturas digitais (estudadas no Captulo 3 1) esto entre as tecnologias centrais utilizadas e se baseiam em algoritmos numricos e na teoria dos nmeros.

    Na indstria e em outras instalaes comerciais, muitas vezes importante alocar recursos escassos da maneira mais benfica. Uma empresa petrolfera talvez deseje saber onde loca- lizar seus poos para tomar mximo o lucro esperado. Um candidato a presidncia da Re- pblica talvez queira determinar onde gastar dinheiro em publicidade de campanha com a finalidade de ampliar as chances de vencer a eleio. Uma empresa de transporte areo pode designar as tripulaes para os voos da forma menos dispendiosa possvel, certificam

    41 do-se de que cadavo ser atendido e que as regulamentaes do governo relativas a escala

  • das tripulaes sero obedecidas. Um provedor de servios da Internet talvez queira definir onde instalar recursos adicionais para servir de modo mais eficiente a seus clientes. Todos esses so exemplos de problemas que podem ser resolvidos com o uso da programao li- near, que estudaremos no Captulo 29.

    Embora alguns dos detalhes desses exemplos estejam alm do escopo deste livro, fornecere- mos tcnicas bsicas que se aplicam a esses problemas e a essas reas de problemas. Tambm mostraremos neste livro como resolver muitos problemas concretos, inclusive os seguintes:

    Temos um mapa rodovirio no qual a distncia entre cada par de intersees adjacentes marcada, e nossa meta determinar a menor rota de uma interseo at outra. O nmero de rotas possveis pode ser enorme, ainda que sejam descartadas as rotas que cruzam sobre si mesmas. Como escolher qual de todas as rotas possveis a mais curta? Aqui, modelamos o mapa rodovirio (que ele prprio um modelo das estradas reais) como um grafo (o que veremos no Captulo 10 e no Apndice B) e desejamos encontrar o caminho mais curto de um vrtice at outro no grafo. Veremos como resolver esse problema de forma eficiente no Captulo 24.

    Temos uma sequncia (A,, A,, ..., A,) de n matrizes e desejamos determinar seu produto A d 2 ... A,. Como a multiplicao de matrizes associativa, existem vrias ordens de mul- tiplicao vlidas. Por exemplo, se n = 4, podemos executar as multiplicaes de matri- zes como se o produto estivesse entre parnteses em qualquer das seguintes ordens: (A1(A2(Afi4))) > (A1((A2'%)A4)) , ((A1A2) (Afi4)) , ((A1(Afi3))A4) OU (((A1A2)A3)A4)- Se essas matrizes forem todas quadradas (e portanto tiverem o mesmo tamanho), a ordem de multiplicao no afetar o tempo de durao das multiplicaes de matrizes. Porm, se essas matrizes forem de tamanhos diferentes (ainda que seus tamanhos sejam compat- veis para a multiplicao de matrizes), ento a ordem de multiplicao pode fazer uma di- ferena muito grande. O nmero de ordens de multiplicao possveis exponencial em n, e assim tentar todas as ordens possveis pode levar um tempo muito longo. Veremos no Captulo 15 como usar uma tcnica geral conhecida como programao dinmica para resolver esse problema de modo muito mais eficiente.

    Temos uma equao ax = b (mod n), onde a, b e n so inteiros, e desejamos encontrar to- dos os inteiros x, mdulo n, que satisfazem a equao. Pode haver zero, uma ou mais de uma soluo. Podemos simplesmente experimentarx = 0, 1, ..., n - 1 em ordem, mas o Captulo 3 1 mostra um mtodo mais eficiente.

    Temos n pontos no plano e desejamos encontrar a envoltria convexa desses pontos. A envoltria convexa o menor polgono convexo que contm os pontos. Intuitivamente, podemos imaginar que cada ponto representado por um prego furado a uma tbua. A envoltria convexa seria representada por um elstico apertado que cercasse todos os pregos. Cada prego pelo qual o elstico passa um vrtice da envoltria convexa. (Veja um exemplo na Figura 33.6.) Quaisquer dos 2, subconjuntos dos pontos poderiam ser os vrtices da envoltria convexa. Saber quais pontos so vrtices da envoltria convexa no suficiente, pois tambm precisamos conhecer a ordem em que eles aparecem. Portanto, h muitas escolhas para os vrtices da envoltria convexa. O Captulo 33 apresenta dois bons mtodos para se encontrar a envoltria convexa.

    Essas listas esto longe de esgotar os exemplos (como voc novamente j deve ter imagina- do pelo peso deste livro), mas exibem duas caractersticas comuns a muitos algoritmos inte- ressantes.

    1. Existem muitas solues candidatas, a maioria das quais no aquilo que desejamos. Encontrar a soluo que queremos pode representar um desafio.

  • 2. Existem aplicaes prticas. Dos problemas da lista anterior, o caminho mais curto fornece os exemplos mais fceis. Uma empresa de transportes que utiliza caminhes ou vages ferrovirios tem interesse financeiro em encontrar os caminhos mais curtos em uma rede ferroviria ou rodoviria, porque percursos menores resultam em menor trabalho e menor consumo de combustvel. Ou ento, um n de roteamento na Internet pode precisar encontrar o caminho mais curto atravs da rede, a fim de rotear uma mensagem com rapidez.

    Estruturas de dados

    Este livro tambm contm vrias estruturas de dados. Uma estrutura de dados um meio para armazenar e organizar dados com o objetivo de facilitar o acesso e as modificaes. Nenhuma es- trutura de dados nica funciona bem para todos os propsitos, e assim importante conhecer os pontos fortes e as limitaes de vrias delas.

    Tcnica

    Embora possa usar este livro como um "livro de receitas" para algoritmos, algum dia voc poder encontrar um problema para o qual no seja possvel descobrir prontamente um algoritmo publi- cado (muitos dos exerccios e problemas deste livro, por exemplo!). Este livro lhe ensinar tcni- cas de projeto e anlise de algoritmos, de forma que voc possa desenvolver algoritmos por conta prpria, mostrar que eles fornecem a resposta correta e entender sua eficincia.

    Problemas dXceis

    A maior parte deste livro trata de algoritmos eficientes. Nossa medida habitual de eficincia a velocidade, isto , quanto tempo um algoritmo demora para produzir seu resultado. Porm, existem alguns problemas para os quais no se conhece nenhuma soluo eficiente. O Captulo 34 estuda um subconjunto interessante desses problemas, conhecidos como NP-completos.

    Por que os problemas NP-completos so interessantes? Primeiro, embora ainda no tenha sido encontrado nenhum algoritmo eficiente para um problema NP-completo, ningum jamais provou que no possvel existir um algoritmo eficiente para esse fim. Em outras palavras, desconhecemos se existem ou no algoritmos eficientes para problemas NP-completos. Em segundo lugar, o conjunto de problemas NP-completos tem a propriedade notvel de que, se existe um algoritmo eficiente para qualquer um deles, ento existem algoritmos eficientes para todos. Esse relacionamento entre os problemas NP-completos torna a falta de solues eficientes ainda mais torturante. Em terceiro lugar, vrios problemas NP-completos so semelhantes, mas no idnticos, a problemas para os quais conhecemos algoritmos eficientes. Uma pequena mudana no enunciado do problema pode provocar uma grande alterao na eficincia do melhor algoritmo conhecido.

    valioso conhecer os problemas NP-completos, porque alguns deles surgem com frequncia surpreendente em aplicaes reais. Se for chamado a produzir um algoritmo eficiente para um problema NP-completo, provvel que voc perca muito tempo em uma busca infrutfera. Por outro lado, se conseguir mostrar que o problema NP-completo, voc poder em vez disso dedicar seu tempo ao desenvolvimento de um algoritmo eficiente que oferea uma soluo boa, embora no seja a melhor possvel.

    Como um exemplo concreto, considere uma empresa de transporte por caminho com um armazm central. A cada dia, ela carrega o caminho no armazm e o envia a diversos locais para efetuar entregas. No final do dia, o caminho tem de estar de volta ao armazm, a fim de ser preparado para receber a carga do dia seguinte. Para reduzir custos, a empresa deve selecionar uma ordem de paradas de entrega que represente a menor distncia total a ser percorrida pelo

    1 caminho. Esse problema o famoso "problema do caixeiro-viajante", e NP-completo. Ele no

  • tem nenhum algoritmo eficiente conhecido. Contudo, sob certas hipteses, h algoritmos eficientes que fornecem uma distncia total no muito acima da menor possvel. O Captulo 35 discute esses "algoritmos de aproximao7'.

    Exerccios

    1.1-1 Fornea um exemplo real no qual aparea um dos problemas computacionais a seguir: ordena- o, determinao da melhor ordem para multiplicao de matrizes ou localizao da envoltria convexa.

    1.1-2 . Alm da velocidade, que outras medidas de eficincia poderiam ser usadas em uma configura- o real?

    1.1-3 Selecione uma estrutura de dados que voc j tenha visto antes e discuta seus pontos fortes e suas limitaes.

    1 .I4 Em que aspectos os problemas do caminho mais curto e do caixeiro-viajante anteriores so se- melhantes? Em que aspectos eles so diferentes?

    1 .l-5 Mostre um problema real no qual apenas a melhor soluo servir. Em seguida, apresente um problema em que baste uma soluo que seja "aproximadamente7' a melhor.

    1.2 Algoritmos como uma tecnologia Suponha que os computadores fossem infinitamente rpidos e que a memria do computador fosse livre. Voc teria alguma razo para estudar algoritmos? A resposta sim, se no por outra razo, pelo menos porque voc ainda gostaria de demonstrar que o mtodo da sua soluo termina, e o faz com a resposta correta.

    Se os computadores fossem infinitamente rpidos, qualquer mtodo correto para resolver um problema serviria. provvel que voc quisesse que sua implementao estivesse dentro dos limites da boa prtica de engenharia de software (isto , que ela fosse bem documentada e projetada) mas, com maior frequncia, voc utilizaria o mtodo que fosse o mais fcil de implementar.

    claro que os computadores podem ser rpidos, mas no so infinitamente rpidos. A memria pode ser de baixo custo, mas no gratuita. Assim, o tempo de computao um recurso limitado, bem como o espao na memria. Esses recursos devem ser usados de forma sensata, e algoritmos eficientes em termos de tempo ou espao ajudaro voc a us-los.

    Eficincia

    Algoritmos criados para resolver o mesmo problema muitas vezes diferem de forma drstica em sua eficincia. Essas diferenas podem ser muito mais significativas que as diferenas relativas a hardware e software.

    Veremos no Captulo 2, como exemplo, dois algoritmos para ordenao. O primeiro, conhe- cido como ordenaopor insero, leva um tempo aproximadamente igual a cln2 para orde- nar n itens, onde c, uma constante que no depende de n. Isto , ela demora um tempo aproxi- madamente proporcional a n2. O segundo, de ordenaopor intercalao, leva um tempo aproximadamente igual a c2n lg n, onde Ig n representa log2 n e c2 outra constante que tam-

    17

  • bm no depende de n. A ordenao por insero normalmente tem um fator constante menor que a ordenao por intercalao; e assim, c, < c,. Veremos que os fatores constantes podem ser muito menos significativos no tempo de execuo que a dependncia do tamanho da entrada n. Onde a ordenao por intercalao tem um fator lg n em seu tempo de execuo, a ordenao por insero tem um fator n, que muito maior. Embora a ordenao por insero em geral seja mais rpida que a ordenao por intercalao para pequenos tamanhos de entradas, uma vez que o tamanho da entrada n se tornar grande o suficiente, a vantagem da ordenao por interca- lao de lg n contra n compensar com sobras a diferena em fatores constantes. Independente do quanto c, seja menor que c,, sempre haver um ponto de passagem alm do qual a ordena- o por intercalao ser mais rpida.

    Como um exemplo concreto, vamos comparar um computador mais rpido (computador A) que executa a ordenao por insero com um computador mais lento (computador B) que executa a ordenao por intercalao. Cada um deles deve ordenar um arranjo de um milho de nmeros.

    Suponha que o computador A execute um bilho de instrues por segundo e o computador B execute apenas dez milhes de instrues por segundo; assim, o computador A ser 100 vezes mais rpido que o computador B em capacidade bruta de computao. Para tornar a diferena ain- da mais drstica, suponha que o programador mais astucioso do mundo codifique a ordenao por insero em linguagem de mquina para o computador A, e que o cdigo resultante exija 2n2 instrues para ordenar n nmeros. (Aqui, cl = 2 .) Por outro lado, a ordenao por intercalao programada para o computador B por um programador mdio que utiliza uma linguagem de alto nvel com um compilador ineficiente, com o cdigo resultante totalizando 50n lg n instrues (de forma que c, = 50). Para ordenar um milho de nmeros, o computador A demora

    2. (10 ) instrues = 2000 segundos ,

    10 instrues/segundo

    enquanto o computador B demora

    50 .10 lg 10 instrues e 100 segundos 10' instrues/segundo

    Usando um algoritmo cujo tempo de execuo cresce mais lentamente, at mesmo com um compilador fraco, o computador B funciona 20 vezes mais rpido que o computador A! A vantagem da ordenao por intercalao ainda mais pronunciada quando ordenamos dez milhes de nmeros: onde a ordenao por insero demora aproximadamente 2,3 dias, a ordenao por intercalao demora menos de 20 minutos. Em geral, medida que o tamanho do problema aumenta, tambm aumenta a vantagem relativa da ordenao por intercalao.

    Algoritmos e outras tecnologias

    O exemplo anterior mostra que os algoritmos, como o hardware de computadores, constituem uma temologia. O desempenho total do sistema depende da escolha de algoritmos eficientes tanto quanto da escolha de hardware rpido. Da mesma maneira que esto havendo rpidos avanos em outras tecnologias computacionais, eles tambm esto sendo obtidos em algorit- mos.

    Voc poderia indagar se os algoritmos so verdadeiramente to importantes nos computa- dores contemporneos em comparao com outras tecnologias avanadas, como:

    Hardware com altas taxas de clock, pipelines e arquiteturas superescalares.

    81 Interfaces grficas do usurio (GUIs) intuitivas e fceis de usar.

  • Sistemas orientados a objetos.

    Redes locais e remotas.

    A resposta sim. Embora existam algumas aplicaes que no exigem explicitamente contedo algortmico no nvel da aplicao (por exemplo, algumas aplicaes simples baseadas na Web), a maioria tambm requer um certo grau de contedo algortmico por si s. Por exemplo, considere um servio da Web que determina como viajar de um local para outro. (Havia diversos servios desse tipo no momento em que este livro foi escrito.) Sua implementao dependeria de hardware rpido, de uma interface grfka do usurio, de redes remotas e tambm, possivelmente, de orientao a objetos. Contudo, ele tambm exigiria algoritmos para certas operaes, como localizao de rotas (talvez empregando um algoritmo de caminho mais curto), interpretao de mapas e interpolao de endereos.

    Alm disso, at mesmo uma aplicao que no exige contedo algortmico no nvel da aplicao depende muito de algoritmos. Ser que a aplicao depende de hardware rpido? O projeto de hardware utilizou algoritmos. A aplicao depende de interfaces grficas do usurio? O projeto de qualquer GUI depende de algoritmos. A aplicao depende de rede? O roteamento em redes depende muito de algoritmos. A aplicao foi escrita em uma linguagem diferente do cdigo de mquina? Ento, ela foi processada por um compilador, um interpretador ou um assembler, e todos fazem uso extensivo de algoritmos. Os algoritmos formam o ncleo da maioria das tecnologias usadas em computadores contemporneos.

    Alm disso, com a capacidade cada vez maior dos computadores, ns os utilizamos para resolver problemas maiores do que nunca. Como vimos na comparao anterior entre ordenao por insero e ordenao por intercalao, em problemas de tamanhos maiores, as diferenas na eficincia dos algoritmos se tornam particularmente importantes.

    Uma slida base de conhecimento e tcnica de algoritmos uma caracterstica que separa os programadores verdadeiramente qualificados dos novatos. Com a moderna tecnologia computacional, voc pode executar algumas tarefas sem saber muito sobre algoritmos; porm, com uma boa base em algoritmos, possvel fazer muito, muito mais.

    Exerccios

    1.2-1 Fornea um exemplo de aplicao que exige contedo algortmico no nvel da aplicao e discu- ta a funo dos algoritmos envolvidos.

    1.2-2 Vamos supor que estamos comparando implementaes de ordenao por insero e ordena- o por intercalao na mesma mquina. Para entradas de tamanho n, a ordenao por insero executada em 8n2 etapas, enquanto a ordenao por intercalao executada em 64n Ig n eta- pas. Para que valores de n a ordenao por insero supera a ordenao por intercalao?

    1.2-3 Qual o menor valor de n tal que um algoritmo cujo tempo de execuo 100n2 funciona mais rpido que um algoritmo cujo tempo de execuo 2n na mesma mquina?

    Problemas 1-1 Comparao entre tempos de execuo Para cada funo f(n) e cada tempo t na tabela a seguir, determine o maior tamanho n de um pro- blema que pode ser resolvido no tempo t, supondo-se que o algoritmo para resolver o problema demore f(n) microssegundos.

  • Notas do captulo

    lg n

    Jn n

    n Ig n

    n2

    n3

    2"

    n!

    Existem muitos textos excelentes sobre o tpico geral de algoritmos, inclusive os de Aho, Hop- croft e Ullman [5,6], Baase e Van Gelder [26], Brassard e Bratley [46,47], Goodrich e Tamassia [128], Horowitz, Sahni e Rajasekaran [158], Kingston [179], Knuth [182, 183, 1851, Kozen [193], Manber [210], Mehlhorn [217,218,219], Purdom e Brown [252], Reingold, Nievergelt e Deo [257], Sedgewick [269], Skiena [280] e Wilf [315]. Alguns dos aspectos mais prticos do projeto de algoritmos so discutidos por Bentley [39, 401 e Gonnet [126]. Pesquisas sobre o campo dos algoritmos tambm podem ser encontradas no Handbook of Theoretical Computer Science, Volume A [302] e no CRC Handbook on Algorithms and Theory of Computation [24]. Avaliaes dos algoritmos usados em biologia computacional podem ser encontradas em li- vros-texto de Gusfield [136], Pevzner [240], Setubal e Medinas [272], e Waterman [309].

    1 segundo 1 minuto 1 hora 1 dia 1 ms 1 ano 1 sculo

  • Capitulo 2

    Conceitos bsicos

    Este captulo tem o objetivo de familiariz-lo com a estrutura que usaremos em todo o livro para refletir sobre o projeto e a anlise de algoritmos. Ele autnomo, mas inclui diversas referncias ao material que ser apresentado nos Captulos 3 e 4. (E tambm contm diversos somatrios, que o Apndice A mostra como resolver.)

    Comearemos examinando o problema do algoritmo de ordenao por insero para re- solver o problema de ordenao apresentado no Captulo 1. Definiremos um "pseudocdigo" que dever ser familiar aos leitores que tenham estudado programao de computadores, e o empregaremos com a finalidade de mostrar como sero especificados nossos algoritmos. Ten- do especificado o algoritmo, demonstraremos ento que ele efetua a ordenao corretamente e analisaremos seu tempo de execuo. A anlise introduzir uma notao centrada no modo como o tempo aumenta com o nmero de itens a serem ordenados. Seguindo nossa discusso da ordenao por insero, introduziremos a abordagem de dividir e conquistar para o proje- to de algoritmos e a utilizaremos com a finalidade de desenvolver um algoritmo chamado or- denao por intercalao. Terminaremos com uma anlise do tempo de execuo da ordena- o por intercalao.

    2.1 Ordenao por insero Nosso primeiro algoritmo, o de ordenao por insero, resolve o p r o b b m a de ordenao introduzido no Captulo 1:

    Entrada: Uma sequncia de n nmeros (a,, a,, ..., a,).

    Sada: Uma permutao (reordenao) (ai, ai, . . . , a;) da sequncia de entrada, tal que ai 5 ai 5 ... S a:, .

    Os nmeros que desejamos ordenar tambm so conhecidos como chaves. Neste livro, descreveremos tipicamente algoritmos como programas escritos em umpseu-

    docdigo muito semelhante em vrios aspectos a C, Pascal ou Java. Se j conhece qualquer des- sas linguagens, voc dever ter pouca dificuldade para ler nossos algoritmos. O que separa o pseudocdigo do cdigo "real" que, no pseudocdigo, empregamos qualquer mtodo expres- sivo para especificar de forma mais clara e concisa um dado algoritmo. s vezes, o mtodo mais claro a linguagem comum; assim, no se surpreenda se encontrar uma frase ou sentena em nosso idioma (ou em ingls) embutida no interior de uma seo de cdigo "real". Outra diferen- 1 I I

  • a entre o pseudocdigo e o cdigo real que o pseudocdigo em geral no se relaciona com questes de engenharia de software. As questes de abstrao de dados, modularidade e trata- mento de erros so frequentemente ignoradas, com a finalidade de transmitir a essncia do al- goritmo de modo mais conciso.

    FIGURA 2.1 Ordenando cartas com o uso da ordenao por insero

    Comearemos com a ordenao por insero, um algoritmo eficiente para ordenar um nmero pequeno de elementos. A ordenao por insero funciona da maneira como muitas pessoas ordenam as cartas em um jogo de bridge ou pquer. Iniciaremos com a mo esquerda vazia e as cartas viradas com a face para baixo na mesa. Em seguida, removeremos uma carta de cada vez da mesa, inserindo-a na posio correta na mo esquerda. Para encontrar a posio cor- reta de uma carta, vamos compar-la a cada uma das cartas que j esto na mo, da direita para a esquerda, como ilustra a Figura 2.1. Em cada instante, as cartas seguras na mo esquerda so or- denadas; essas cartas eram originalmente as cartas superiores da pilha na mesa.

    Nosso pseudocdigo para ordenao por insero apresentado como um procedimento chamado INSERTION-SORT, que toma como parmetro um arranjo A[ 1 .. n] contendo uma se- quncia de comprimento n que dever ser ordenada. (No cdigo, o nmero n de elementos em A denotado por comprimento[A] .) Os nmeros da entrada so ordenados n o local: os n- meros so reorganizados dentro do arranjo A, com no mximo um nmero constante deles ar- mazenado fora do arranjo em qualquer instante. O arranjo de entradaA conter a sequncia de sada ordenada quando INSERTION-SORT terminar.

    FIGURA 2.2 A operao de INSERTION-SORT sobre o arranjoA = ( 5 , 2 , 4 , 6 , 1,3) . Os ndices do arranjo aparecem acima dos retngulos e os valores armazenados nas posies do arranjo aparecem dentro dos retngulos. (a)-(e) As iteraes do loop for das linhas 1 a 8. Em cada iterao, o retngulo preto contm a chave obtida de AV], que comparada aos valores contidos nos retngulos sombreados a sua esquer- da, no teste da linha 5. Setas sombreadas mostram os valores do arranjo deslocados uma posio a direi- ta na linha 6 , e setas pretas indicam para onde a chave deslocada na linha 8. (f) O arranjo ordenado fi-

  • INSERTION-SORT(A) 1 for j t 2 to comprimento [A] 2 do chave t AV] 3 D Inserir Av] na sequncia ordenada A[l..j - 11. 4 i t j - 1 5 while i > O e A[i] > chave 6 do A[i + 11 t A[i] 7 i t i - 1 8 A[i + 11 t chave

    Loops invariantes e a correo da ordenao por insero A Figura 2.2 mostra como esse algoritmo funciona paraA = (5, 2, 4,6, 1, 3). O ndice j indica a "carta atual" sendo inserida na mo. No incio de cada iterao do loop for "externo", indexado porj, o subarranjo que consiste nos elementosA[l .. j- 11 constitui a mo atualmente ordenada, e os elementos AV + 1 .. n] correspondem a pilha de cartas ainda na mesa. Na verdade, os ele- mentosA[l .. j - 11 so os elementos que estavam originalmente nas posies de 1 a j - 1, mas agora em sequncia ordenada. Enunciamos formalmente essas propriedades de A[l .. j - 11 como um loop invariante:

    No comeo de cada iterao do loop for das linhas 1 a 8, o subarranjoA[ 1 . . j - 11 consiste nos elementos contidos originalmente em A[l .. j - 11, mas em sequncia ordenada.

    Usamos loops invariantes para nos ajudar a entender por que um algoritmo correto. Deve- mos mostrar trs detalhes sobre um loop invariante:

    Inicializao: Ele verdadeiro antes da primeira iterao do loop.

    Manuteno: Se for verdadeiro antes de uma iterao do loop, ele permanecer verdadeiro an- tes da prxima iterao.

    Trmino: Quando o loop termina, o invariante nos fornece uma propriedade til que ajuda a mostrar que o algoritmo correto.

    Quando as duas primeiras propriedades so vlidas, o loop invariante verdadeiro antes de toda iterao do loop. Note a semelhana em relao induo matemtica; nesta ltima, para provar que uma propriedade vlida, voc demonstra um caso bsico e uma etapa indutiva. Aqui, mostrar que o invariante vlido antes da primeira iterao equivalente ao caso bsico, e mostrar que o invariante vlido de uma iterao para outra equivale a etapa indutiva.

    A terceira propriedade talvez seja a mais importante, pois estamos usando o loop invariante para mostrar a correo. Ela tambm difere do uso habitual da induo matemtica, em que a etapa indutiva usada indefinidamente; aqui, paramos a "induo" quando o loop termina.

    Vamos ver como essas propriedades so vlidas para ordenao por insero:

    Inicializao: Comeamos mostrando que o loop invariante vlido antes da primeira iterao do loop, quando j = 2.' Ento, o subarranjo A[l . . j - 11 consiste apenas no nico elemento A[1], que de fato o elemento original emA[l] . Alm disso, esse subarranjo ordenado (de forma trivial, claro), e isso mostra que o loop invariante vlido antes da primeira iterao do loop.

    Quando o loop um loop for, o momento em que verificamos o loop invariante imediatamente antes da primeira iterao ocorre logo aps a atribuio inicial varivel do contador de loop e imediatamente antes do primeiro teste no cabealho do loop. No caso de INSERTION-SORT, esse instante ocorre aps a atribuio de 2 varivelj, mas antes do primeiro teste para verificar se j 2 compr2mento[A]. 1 i3

  • Manuteno: Em seguida, examinamos a segunda propriedade: a demonstrao de que cada iterao mantm o loop invariante. Informalmente, o corpo do loop for exterior funciona deslocando-se AV - 11, AV - 21, AV - 31 e da por diante uma posio a direita, at ser encon- trada a posio adequada para AV] (linhas 4 a 7) , e nesse ponto o valor de Ap] inserido (li- nha 8). Um tratamento mais formal da segunda propriedade nos obrigaria a estabelecer e mostrar um loop invariante para o loop whiie "interno". Porm, nesse momento, preferi- mos no nos prender a tal formalismo, e assim contamos com nossa anlise informal para mostrar que a segunda propriedade vlida para o loop exterior.

    Trmino: Finalmente, examinamos o que ocorre quando o loop termina. No caso da ordenao por insero, o loop for externo termina quandoj excede n, isto , quando j = n + 1. Substi- tuindo j por n + 1 no enunciado do loop invariante, temos que o subarranjo A[ 1 . . n] consis- te nos elementos originalmente contidos emA[l .. n], mas em sequncia ordenada. Contu- do, o subarranjo A[l .. n] o arranjo inteiro! Desse modo, o arranjo inteiro ordenado, o que significa que o algoritmo correto.

    Empregaremos esse mtodo de loops invariantes para mostrar a correo mais adiante neste captulo e tambm em outros captulos.

    Convenes de pseudocdigo

    Utilizaremos as convenes a seguir em nosso pseudocdigo.

    1. O recuo (ou endentao) indica uma estrutura de blocos. Por exemplo, o corpo do loop for que comea na linha 1 consiste nas linhas 2 a 8, e o corpo do loop while* que comea na linha 5 contm as linhas 6 e 7, mas no a linha 8. Nosso estilo de recuo tambm se apli- ca a instrues if-then-else. O uso de recuo em lugar de indicadores convencionais de es- trutura de blocos, como instrues begin e end, reduz bastante a desordem ao mesmo tempo que preserva, ou at mesmo aumenta, a ~ l a reza .~

    As construes de loops whiie, for e repeat e as construes condicionais if, then e else tm interpretaes semelhantes as que apresentam em asc cal.^ Porm, existe uma dife- rena sutil com respeito a loops for: em Pascal, o valor da varivel do contador de loop indefinido na sada do loop mas, neste livro, o contador do loop retm seu valor aps a sa- da do loop. Desse modo, logo depois de um loop for, o valor do contador de loop o va- lor que primeiro excedeu o limite do loop for. Usamos essa propriedade em nosso argu- mento de correo para a ordenao por insero. O cabealho do loop for na linha 1 f o r j t 2 to comprimento [A], e assim, quando esse loop termina, j = comprimento [A] + 1 (ou, de forma equivalente, j = n + 1, pois n = comprimento[A]).

    3. O smbolo "D" indica que o restante da linha um comentrio.

    4. Uma atribuio mltipla da forma i t j t e atribui as variveis i e j o valor da expresso e; ela deve ser tratada como equivalente a atribuioj t e seguida pela atribuio i tj.

    5. Variveis (como i, j e chave) so locais para o procedimento dado. No usaremos variveis globais sem indicao explcita.

    2 ~ m linguagens de programao reais, em geral no aconselhvel usar o recuo sozinho para indicar a estrutura de blocos, pois os nveis de recuo so difceis de descobrir quando o cdigo se estende por vrias pginas. 'A maioria das linguagens estruturadas em blocos tem construes equivalentes, embora a sintaxe exata possa diferir da sintaxe de Pascal. * Manteremos na edio brasileira os nomes das instrues e dos comandos de programao (destacados em negrito) em ingls, bem como os ttulos dos algoritmos, conforme a edio original americana, a fim de facilitar o processo de converso para uma linguagem de programao qualquer, caso necessrio. Por exemplo, usaremos while em vez de i r l enquanto. (N.T.)

  • 6. Elementos de arranjos so acessados especificando-se o nome do arranjo seguido pelo n- dice entre colchetes. Por exemplo, A[i] indica o i-simo elemento do arranjo A. A nota- o ".." usada para indicar um intervalo de valores dentro de um arranjo. Desse modo, A [ l .. j] indica o subarranjo de A que consiste nos j elementos A[l], A[2], ..., AV].

    7. Dados compostos esto organizados tipicamente em objetos, os quais so constitu- dos por atributos ou campos. Um determinado campo acessado usando-se o nome do campo seguido pelo nome de seu objeto entre colchetes. Por exemplo, tratamos um arranjo como um objeto com o atributo comprimento indicando quantos elemen- tos ele contm. Para especificar o nmero de elementos em um arranjo A, escrevemos comprimento[A]. Embora sejam utilizados colchetes para indexao de arranjos e atributos de objetos, normalmente ficar claro a partir do contexto qual a interpreta- o pretendida.

    Uma varivel que representa um arranjo ou um objeto tratada como um ponteiro para os dados que representam o arranjo ou objeto. Para todos os campos f de um objeto x, a definio de y t x causa&] = flx] . Alm disso, se definirmos agoraflx] t 3, ento da em diante no apenasflx] = 3, mas tambm&] = 3. Em outras palavras, x e y apontaro para ("sero") o mesmo objeto aps a atribuio y t x.

    s vezes, um ponteiro no far referncia a nenhum objeto. Nesse caso, daremos a ele o valor especial NIL.

    8. Parmetros so passados a um procedimentopor valor: o procedimento chamado rece- be sua prpria cpia dos parmetros e, se ele atribuir um valor a um parmetro, a mudan- a no ser vista pela rotina de chamada. Quando objetos so passados, o ponteiro para os dados que representam o objeto copiado, mas os campos do objeto no o so. Por exemplo, se x um parmetro de um procedimento chamado, a atribuio x t y dentro do procedimento chamado no ser visvel para o procedimento de chamada. Contudo, a atribuioflx] t 3 ser visvel.

    9. Os operadores booleanos "e" e "ou" so operadores de curto-circuito. Isto , quando avaliamos a expresso "x e y", avaliamos primeiro x. Se x for avaliado como FALSE, ento a expresso inteira no poder ser avaliada como TRUE, e assim no avaliaremos y. Se, por outro lado, x for avaliado como TRUE, teremos de avaliar y para determinar o valor da ex- presso inteira. De forma semelhante, na expresso "x ou y", avaliamos a expresso y so- mente se x for avaliado como FALSE. Os operadores de curto-circuito nos permitem es- crever expresses booleanas como "x , . , NIL eflx] = y" sem nos preocuparmos com o que acontece ao tentarmos avaliarflx] quando x NIL.

    Exerccios

    2.1-1 Usando a Figura 2.2 como modelo, ilustre a operao de INSERTION-SORT no arranjoA = (31, 41, 59, 26, 41, 58).

    2.1-2 Reescreva o procedimento INSERTION-SORT para ordenar em ordem no crescente, em vez da ordem no decrescente.

    2.1-3 Considere o problema de pesquisa :

    Entrada: Uma sequncia de n nmeros A = (al, a2, ..., an) e um valor v.

    Sada: Um ndice i tal que v = A[i] ou o valor especial NIL, se v no aparecer em A. l l5

  • Escreva o pseudocdigo parapesquisa linear, que faa a varredura da sequncia, procurando por v. Usando um loop invariante, prove que seu algoritmo correto. Certifique-se de que seu loop invariante satisfaz s trs propriedades necessrias.

    2.1-4 Considere o problema de somar dois inteiros binrios de n bits, armazenados em dois arranjos de n elementosA e B. A soma dos dois inteiros deve ser armazenada em forma binria em um ar- ranjo de (n + 1) elementos C. Enuncie o problema de modo formal e escreva o pseudocdigo para somar os dois inteiros.

    2.2 Anlise de algoritmos Analisar um algoritmo significa prever os recursos de que o algoritmo necessitar. Ocasional- mente, recursos como memria, largura de banda de comunicao ou hardware de computador so a principal preocupao, mas com frequncia o tempo de computao que desejamos me- dir. Em geral, pela anlise de vrios algoritmos candidatos para um problema, pode-se identifi- car facilmente um algoritmo mais eficiente. Essa anlise pode indicar mais de um candidato vi- vel, mas vrios algoritmos de qualidade inferior em geral so descartados no processo.

    Antes de podermos analisar um algoritmo, devemos ter um modelo da tecnologia de imple- mentao que ser usada, inclusive um modelo dos recursos dessa tecnologia