projetos de algoritmos - ziviani, nivio

Upload: leandro-silva

Post on 09-Jul-2015

400 views

Category:

Documents


5 download

TRANSCRIPT

Maria, esposa e companheira, Patricia e Paula, nossas filhas.

Dados Internacionais de Catalogao na Publicao (CIP) ( C i m a r a B r a s i l e i r a do L i v r o , S P, B r a s i l ) Ziviani, Nivio Projeto de algoritmos c o m

implementaes

Pascal C / Nivio Ziviani. -- 4. ad. -- So Paulo : Pioneira, 1999. -- (Pioneira Informtica)

Bibliografia.ISBN 85-221-

1. Algoritmos 2. C (Linguagem de programao para computadores) 3. Dados - Estruturas (Cincia da computao). 4. PASCAL (Linguagem de programao para computadores) I. Titulo. II. Srie

98-5286

CDD-005.1

ndices para catlogo sistemtico: 1. Algoritmos : Computadores : Programao : Processamento de dados 005.1

Projeto de AlgoritmosCom Implementaesem Pascal e C

PIONEIRA INFORMTICACoordenador:

Routo TeradaConselho Diretor: Lvio Giosa Ulf Gregor Baranow

Projeto de AlgoritmosCom Implementaes em Pascal e C

Nivio Ziviani, Ph.D.Professor TitularUniversidade Federal de Minas Gerais Departmento de Cincia d Computao

44 Edio

Este livro foi composto, revisado. paginado pelo autor. A Pioneira, a partir dos fotolitos, imprimiu-o.

Capa do Riccardo Fanucchi

Nenhuma parte deste livro poder ser reproduzida sejam quais forem os meios empregados sem a permisso, por escrito, da Editora. Aos infratores se aplicam as sanes previstas nos artigos 102, 104, 106 e 107 da Lei n 9.610 de 19 de fevereiro de 1998.

Copyright 1999 Todos os direitos reservados por ENIO MATHEUS GUAllELLI & CIA. LTDA. 02515-050 Praa Dirceu de Lima, 313 Telefone: (011) 858-3199 Fax: (011) 858-0443 So Paulo SP e-mail: [email protected] Impresso no Brasil Printed inBrazil

PrefcioEste livro apresenta uma introduo ao estudo de algoritmos computacionais. As principais tcnicas de projeto de algoritmos so ensinadas atravs da explicao detalhada de algoritmos e estruturas de dados para o uso eficiente do computador. Estas explicaes so mantidas o mais simples possvel, mas sem perder a profundidade e o rigor matemtico. O contedo dirigido principalmente para ser utilizado como livro-texto em cursos sobre algoritmos e estruturas de dados. Pelo fato de apresentar muitas implementaes de algoritmos prticos o texto igualmente til para profissionais engajados no desenvolvimento de sistemas de computao e de programas de aplicao. Os algoritmos so apresentados atravs de refinamentos sucessivos at o nvel de uma implementao na linguagem Pascal, o que permite que qualquer pessoa com um mnimo de experincia em programao possa ler o cdigo. Contedo O livro apresenta as principais tcnicas utilizadas para a implementao de estruturas de dados bsicas e de algoritmos para ordenao e pesquisa em memria primria e memria secundria. Os tpicos esto agrupados em cinco captulos, cada um com o seguinte contedo: (i) conceito de algoritmo, estrutura de dados e tipo abstrato de dados, tcnicas de anlise de desempenho de algoritmos, linguagem Pascal; (ii) estruturas de dados bsicas: listas lineares, pilhas e filas; (iii) mtodos de ordenao em memria primria: por insero, por seleo, shellsort, quicksort e heapsort, e em memria secundria: intercalao balanceada; (iv) mtodos de pesquisa em memria primria: pesquisa seqencial, pesquisa binria, rvores de pesquisa e hashing; (v) mtodos de pesquisa em memria secundria: seqencial indexado e rvores B. O estudo do comportamento dos algoritmos tem um papel decisivo no projeto de algoritmos eficientes. Por isso, so apresentadas informaes sobre as caractersticas de desempenho de cada algoritmo apresentado. Entretanto, a parte matemtica utilizada para apresentar os resultados analticos

autocontida e exige muito pouco conhecimento matemtico prvio para ser entendida. A linguagem de programao utilizada para apresentao do refinamento final dos algoritmos apresentados a linguagem Pascal. A vantagem de se usar a linguagem Pascal que os programas se tornam fceis de ser lidos e de ser traduzidos para outras linguagens. Alm disso, todos os algoritmos implementados na linguagem Pascal so tambm implementados na linguagem C. Todo programa Pascal de um captulo tem um programa C correspondente no apndice. Ao Leitor O material apresentado adequado para ser utilizado como livro texto em cursos de graduao em Cincia da Computao e em cursos de extenso para formao de Programadores na rea de Algoritmos e Estruturas de Dados. E recomendvel que o estudante j tenha tido um curso de programao (ou experincia equivalente) em uma linguagem de alto nvel, tal como Pascal ou C, assim como conhecimentos de utilizao de sistemas de computao. Verses anteriores deste livro foram utilizadas na Universidade Federal de Minas Gerais. A disciplina Algoritmos e Estruturas de Dados II do Curso de Bacharelado em Cincia da Computao, com carga horria de 60 horas e um semestre de durao, possui a seguinte ementa: tipos abstratos de dados; introduo a anlise de algoritmos; listas lineares, pilhas e filas; ordenao: seleo direta, insero direta, shellsort, quicksort, heapsort, mergesort e radixsort; pesquisa em tabelas: seqencial, binria e transformao de chave ( hashing); rvores de pesquisa: sem balanceamento, com balanceadamento, tries e patricia. Os tpicos ordenao externa, pesquisa em memria secundria e um estudo mais elaborado de anlise de algoritmos fazem parte da disciplina Algoritmos e Estruturas de Dados III, do mesmo Curso. Ao final de cada captulo so includos exerccios. Alguns exerccios so do tipo questes curtas, para testar os conhecimentos bsicos sobre o material apresentado. Outros exerccios so do tipo questes mais elaboradas, podendo exigir do leitor um trabalho de vrios dias, devendo ser realizado em casa ou em laboratrio. Assim, os exerccios propostos devem ser utilizados em testes e trabalhos prticos para avaliao da aprendizagem. Este texto pode tambm ser utilizado como manual para programadores que j tenham familiaridade com o assunto, pois so apresentadas implementaes de algoritmos de utilidade geral. Os algoritmos propostos so completamente implementados nas linguagens Pascal e C e as operaes envolvidas so descritas atravs da apresentao de exemplos de execuo.

Agradecimentos Uma verso inicial deste texto foi escrita para ser usada no Curso Estruturas de Dados e Algoritmos da I Escola Brasileiro-Argentina de Informtica em fevereiro de 1986, publicada pela Editora da Unicamp sob o ttulo Projeto de Algoritmos e Estruturas de Dados. Gostaria de agradecer a Carlos Jos Pereira de Lucena e Routo Terada por lembrarem do meu nome para participar da I Escola Brasileiro-Argentina de Informtica, o que motivou o desenvolvimento da semente deste texto. Gostaria de agradecer a Cilio Rosa Ziviani, Cleber Hostalcio de Melo, Jos Monteiro da Mata, Lilia Tavares Mascarenhas, Luiz Carlos de Abreu Albuquerque, Regina Helena Bastos Cabral e Rosngela Fernandes pelas contribuies para a primeira verso do texto. Muitos amigos e colegas me auxiliaram na. elaborao deste livro. Agradeo a todos pela ajuda e pelas crticas construtivas. O Departamento de Cincia da Computao da Universidade Federal de Minas Gerais tem proporcionado um excelente ambiente de trabalho. Os meus alunos de extenso, graduao, especializao e ps-graduao, especialmente os alunos das disciplinas Tcnicas de Programao, Algoritmos e Estruturas de Dados e Projeto e Anlise de Algoritmos contriburam significativamente. Vrios erros foram corrigidos como conseqncia da leitura cuidadosa de vrias pessoas, em especial Alberto Henrique Frade Laender, Eduardo Fernandes Barbosa, Jos Nagib Cotrim Arabe, Mrcio Luiz Bunte de Carvalho, Osvaldo Srgio Farhat de Carvalho, Roberto Mrcio Ferreira de Souza e Virglio Augusto Fernandes Almeida, aos quais gostaria de registrar meus agradecimentos. Gostaria de agradecer a Cristina Duarte Murta pela leitura crtica de todo o texto, pelos testes dos programas Pascal e pela execuo dos programas que permitiu o estudo comparativo dos algoritmos de ordenao. A verso C dos algoritmos existe graas ao trabalho paciente de traduo dos programas Pascal conduzido -por Maurcio Antnio de Castro Lima e Wagner Toledo Corra, realizado com o auxlio do programa p2c para traduo automtica de programas em Pascal para programas em C, desenvolvido por Dave Gillespie, do California Institute of Technology, EUA. O livro foi formatado com LATEX, um conjunto de macros para o TEX. Um agradecimento todo especial para Mrcio Luiz Bunte de Carvalho pela imensa ajuda durante todo o trabalho de formatao, incluindo a criao de ambientes especiais em LATEX para este texto, sendo que esta etapa contou tambm com a ajuda de Murilo Silva Monteiro.

Nivio Ziviani Belo Horizonte Dezembro de 1992 Endereo Internet: [email protected]

SumrioPrefcio Lista de Figuras Lista de Tabelas Lista de Programas v xiii xv xvii

1 Introduo 1 1.1 Algoritmos, Estruturas de Dados e Programas ...................................... 1 1.2 Tipos de Dados e Tipos Abstratos de Dados ......................................... 2 1.3 Medida do Tempo de Execuo de um Programa ................................. 3 1.3.1 Comportamento Assinttico de Funes ................................. 11 1.3.2 Classes de Comportamento Assinttico ...................................14 1.4 Tcnicas de Anlise de Algoritmos ...................................................... 18 1.5 Pascal ...................................................................................................... 25 Notas Bibliogrficas .................................................................................... 30 Exerccios ..................................................................................................... 30 2 Estruturas de Dados Bsicas 35 2.1 Listas Lineares ....................................................................................... 35 2.1.1 Implementao de Listas Atravs de Arranjos ........................ 37 2.1.2 Implementao de Listas Atravs de Apontadores ................. 38 2.2 Pilhas .......................................................................................................47 2.2.1 Implementao de Pilhas Atravs de Arranjos ........................48 2.2.2 Implementao de Pilhas Atravs de Apontadores ................. 49 2.3 Filas .........................................................................................................55 2.3.1 Implementao de Filas Atravs de Arranjos .......................... 56 2.3.2 Implementao de Filas Atravs de Apontadores ................... 58 Notas Bibliogrficas .................................................................................... 58 Exerccios ..................................................................................................... 58

SUMRIO 3 Ordenao 69 3.1 Ordenao Interna ................................................................................ 71 3.1.1 Ordenao por Seleo ............................................................. 72 3.1.2 Ordenao por Insero ............................................................ 73 3.1.3 Shellsort ..................................................................................... 76 3.1.4 Quicksort .................................................................................... 78 3.1.5 Heapsort ..................................................................................... 81 3.1.6 Comparao Entre os Mtodos ................................................. 87 3.2 Ordenao Externa ............................................................................... 91 3.2.1 Intercalao Balanceada de Vrios Caminhos ........................ 92 3.2.2 Implementao Atravs de Seleo por Substituio ............. 94 3.2.3 Consideraes Prticas ............................................................. 97 Notas Bibliogrficas ................................................................................... 99 Exerccios .................................................................................................... 99 4 Pesquisa em Memria Primria 107 4.1 Pesquisa Seqencial ........................................................................... 108 4.2 Pesquisa Binria ................................................................................. 110 4.3 Arvores de Pesquisa ........................................................................... 111 4.3.1 Arvores Binrias de Pesquisa Sem Balanceamento .............. 112 4.3.2 Arvores Binrias de Pesquisa Com Balanceamento ............. 117 4.4 Pesquisa Digital ................................................................................... 127 4.5 Transformao de Chave (Hashing) ................................................... 135 4.5.1 Funes de Transformao ..................................................... 136 4.5.2 Listas Encadeadas ................................................................... 137 4.5.3 Open Addressing ..................................................................... 140 Notas Bibliogrficas ................................................................................. 143 Exerccios .................................................................................................. 144 5 Pesquisa em Memria Secundria 155 5.1 Modelo de Computao para Memria Secundria .......................... 157 5.2 Acesso Seqencial Indexado .............................................................. 163 5.3 Arvores de Pesquisa ............................................................................ 169 5.3.1 Arvores B ................................................................................. 170 5.3.2 rvores B* ............................................................................... 182 5.3.3 Acesso Concorrente em Arvores B* ...................................... 184 5.3.4 Consideraes Prticas ........................................................... 189 Notas Bibliogrficas .................................................................................. 192 Exerccios ................................................................................................... 193 A Programas C do Captulo 1 B Programas C do Captulo 2 197 203

SUMRIO C D E F G Programas C do Captulo 3 Programas C do Captulo 4 Programas C do Captulo 5 Caracteres ASCII Referncias Bibliogrficas 217 223 243 253 255 261

ndice

Lista de Figuras1.1 Partio de A em dois subconjuntos ....................................................... 9 1.2 Dominao assinttica de (An) sobre g(n) ......................................... 12 1.3 Operaes com a notao O .................................................................. 13 1.4 Problema do caixeiro viajante ...............................................................18 1.5 Estrutura de um programa Pascal ......................................................... 25 1.6 Registro do tipo pessoa ......................................................................... 28 1.7 Lista encadeada ...................................................................................... 30 2.1 Implementao de uma lista atravs de arranjo ...................................37 2.2 Implementao de uma lista atravs de apontadores .......................... 40 2.3 Classificao dos alunos por NotaFinal ............................................... 43 2.4 Lista de aprovados por Curso ............................................................... 44 2.5 Implementao de uma pilha atravs de arranjo .............................. 48 ............................... 2.6 Implementao de uma pilha atravs de apontadores ......................... 51 2.7 Implementao circular para filas ........................................................ 56 2.8 Implementao de uma fila atravs de apontadores ............................ 58 2.9 Lista circular duplamente encadeada ................................................... 61 2.10 Exemplo de Matriz Esparsa ................................................................ 62 3.1 Exemplo de ordenao por seleo ...................................................... 72 3.2 Exemplo de ordenao por insero ..................................................... 74 3.3 Exemplo de ordenao usando Shellsort ..............................................76 3.4 Partio do vetor .................................................................................... 79 3.5 Exemplo de ordenao usando Quicksort ............................................ 80 3.6 Arvore binria completa ........................................................................ 84 3.7 Arvore binria completa representada por um arranjo . 84 3.8 Construo do heap ............................................................................... 85 3.9 Exemplo de ordenao usando Heapsort ............................................. 86 3.10 Arquivo exemplo com 22 registros .................................................... 93 3.11 Formao dos blocos ordenados iniciais ............................................ 93 3.12 Intercalao-de-3-caminhos ................................................................ 93 3.13 Resultado da primeira passada usando seleo por ubstituio....... 95

LISTA DE FIGURAS 3.14 Conjunto ordenado na primeira passada .............................................. 96 3.15 Intercalao usando seleo por substituio .......................................97 4.1 Exemplo de pesquisa binria para a chave G ......................................... 111 4.2 rvore binria de pesquisa ..................................................................... 113 4.3 Arvore binria de pesquisa completamente balanceada .........................118 4.4 Uma rvore 2-3 e a rvore B binria correspondente ............................ 119 4.5 Arvore SBB ............................................................................................ 119 4.6 Transformaes propostas por Bayer (1972) ........................................120 4.7 Crescimento de uma rvore SBB ........................................................... 123 4.8 Decomposio de uma rvore SBB ........................................................127 4.9 Trie binria ............................................................................................. 129 4.10 Insero das chaves W e K ...................................................................129 4.11 Arvore Patricia ......................................................................................130 4.12 Insero da chave K ............................................................................. 130 4.13 Insero da chave W .............................................................................131 4.14 Lista encadeada em separado ............................................................... 137 4.15 Open addressing ................................................................................140 4.16 Arvore AVL ..........................................................................................143 4.17 Transformaes propostas por Olivi (1980) .......................................146 4.18 Pat array .............................................................................................. 154 5.1 Mapeamento de endereos para paginao ............................................ 159 5.2 Fila de Molduras_de_Pginas .................................................................160 5.3 Endereamento no sistema de paginao ............................................... 163 5.4 Estrutura de um arquivo seqencial indexado ........................................164 5.5 Disco magntico ..................................................................................... 165 5.6 Organizao de um arquivo indexado seqencial para o CD, ROM ................................................................................................... 168 5.7 Arvore binria dividida em pginas ....................................................... 169 5.8 Arvore B de ordem 2 com 3 nveis .........................................................171 5.9 Nodo de uma rvore B de ordem m com 2m registros ........................... 171 5.10 Insero em uma rvore B de ordem 2 .................................................173 5.11 Crescimento de uma rvore B de ordem 2 ........................................... 177 5.12 Retirada da chave 3 na rvore B de ordem m = 1 ................................ 178 5.13 Decomposio de uma rvore B de ordem 2 ........................................181 5.14 Estrutura de uma rvore B* ..................................................................182 5.15 Exemplo de uma rvore B* .................................................................. 184 5.16 Retirada de registros em rvores B* .................................................... 185 5.17 Parte de uma rvore B* ........................................................................ 188

Lista de Tabelas1.1 Comparao dos algoritmos para obter o mximo e o mnimo.......... 10 1.2 Comparao de vrias funes de complexidade ................................ 16 1.3 Influncia do aumento de velocidade dos computadores no tamanho t do problema ..........................................................................17 3.1 Ordem aleatria dos registros ............................................................... 88 3.2 Ordem ascendente dos registros ........................................................... 88 3.3 Ordem descendente dos registros ......................................................... 88 3.4 Influncia da ordem inicial ................................................................... 89 4.1 Nmero de comparaes em uma pesquisa com sucesso para hashing linear .................................................................................................... 141 5.1 Nmero de acessos a disco, no pior caso, para tamanhos variados de pginas e arquivos usando rvore B .................................. 190

Lista de Programas1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 Funo para obter o mximo de um conjunto .......................................5 Implementao direta para obter o mximo e o mnimo . 7 Implementao melhorada para obter o mximo e o mnimo 8 Outra implementao para obter o mximo e o mnimo ..................... 9 Programa para ordenar .......................................................................... 20 Algoritmo recursivo .............................................................................. 21 Verso recursiva para obter o mximo e o mnimo ........................... 23 Programa para copiar arquivo .............................................................. 29

2.1 Estrutura da lista usando arranjo ......................................................... 38 2.2 Operaes sobre listas usando posies contguas de memria 39 2.3 Estrutura da lista usando apontadores ................................................. 40 2.4 Operaes sobre listas usando apontadores ........................................ 41 2.5 Campos do registro de um candidato .................................................. 42 2.6 Primeiro refinamento do programa Vestibular ................................... 43 2.7 Segundo refinamento do programa Vestibular ................................... 44 2.8 Estrutura da lista .................................................................................... 45 2.9 Refinamento final do programa Vestibular ........................................ 46 2.10 Estrutura da pilha usando arranjo ...................................................... 49 2.11 Operaes sobre pilhas usando arranjos ........................................... 50 2.12 Estrutura da pilha usando apontadores ..............................................51 2.13 Operaes sobre pilhas usando apontadores .................................... 52 2.14 Implementao do ET ......................................................................... 54 2.15 Procedimento Imprime utilizado no programa ET ........................... 55 2.16 Estrutura da fila usando arranjo ......................................................... 57 2.17 Operaes sobre filas usando posies contguas de memria ...... 57 2.18 Estrutura da fila usando apontadores ................................................ 59 2.19 Operaes sobre filas usando apontadores ....................................... 60 3.1 Estrutura de um item do arquivo ..........................................................70 3.2 Tipos utilizados na implementao dos algoritmos ........................... 72 3.3 Ordenao por seleo .......................................................................... 73

LISTA DE PROGRAMAS 3.4 Ordenao por insero ........................................................................ 75 3.5 Algoritmo Shellsort .............................................................................. 77 3.6 Procedimento Partio .......................................................................... 79 3.7 Procedimento Quicksort ..........................................................................80 3.8 Procedimento para construir o heap ....................................................... 85 3.9 Procedimento Heapsort ........................................................................... 87 4.1 Estrutura do tipo dicionrio implementado como arranjo .................109 4.2 Implementao das operaes usando arranjo ................................... 109 4.3 Pesquisa binria ..................................................................................... 111 4.4 Estrutura do dicionrio para rvores sem balanceamento ................. 113 4.5 Procedimento para pesquisar na rvore .............................................. 114 4.6 Procedimento para inserir na rvore ....................................................114 4.7 Procedimento para inicializar ...............................................................114 4.8 Programa para criar a rvore ................................................................ 115 4.9 Procedimento para retirar x da rvore ................................................. 116 4.10 Caminhamento central ........................................................................ 117 4.11 Estrutura do dicionrio para rvores SBB ........................................ 120 4.12 Procedimentos auxiliares para rvores SBB .....................................121 4.13 Procedimento para inserir na rvore SBB ........................................ 123 4.14 Procedimento para inicializar a rvore SBB ......................................................... '123 4.15 Procedimento para retirar da rvore SBB ......................................... 126 4.16 Estrutura de dados ............................................................................... 131 4.17 Funes auxiliares ............................................................................... 132 4.18 Procedimento CrieNodos .................................................................... 133 4.19 Algoritmo de pesquisa ........................................................................ 133 4.20 Inicializao da rvore ........................................................................ 133 4.21 Algoritmo de insero ......................................................................... 134 4.22 Implementao de funo de transformao .................................... 137 4.23 Estrutura do dicionrio para listas encadeadas ................................ 138 4.24 Operaes do Dicionrio usando listas encadeadas .........................139 4.25 Estrutura do dicionrio usando open addressing ........................... 141 4.26 Operaes do dicionrio usando open addressing ......................... 142 5.1 Estrutura de dados para o sistema de paginao ................................ 161 5.2 Diferentes tipos de pginas para o sistema de paginao . 162 5.3 Estrutura do dicionrio para rvore B ................................................. 172 5.4 Procedimento para inicializar uma rvore B ................................ 172 ..................................... 5.5 Procedimento para pesquisar na rvore B ........................................ ..173 5.6 Primeiro refinamento do algoritmo Insere na rvore B ................... 174 5.7 Procedimento Insere Na Pgina ..........................................................175 5.8 Refinamento final do algoritmo Insere .............................................. 176 5:9 Procedimento Retira ............................................................................181

LISTA DE PROGRAMAS

5.10 Estrutura do dicionrio para rvore B* ..........................................183 5.11 Procedimento para pesquisar na rvore B* ................................... 183 A.1 A.2 A.3 A.4 A.5 A.6 A.7 A.8 Funo para obter o maior elemento de um vetor ..........................197 Implementao direta para obter o mximo e o mnimo ............... 197 Implementao melhorada para obter o mximo e o mnimo ....... 198 Outra implementao para obter o mximo e o mnimo ................199 Programa para ordenar ...................................................................... 199 Algoritmo recursivo ...........................................................................199 Verso recursiva para obter o mximo e o mnimo ....................... 200 Programa para copiar arquivo .......................................................... 201

B.1 Estrutura da lista usando arranjo ......................................................203 B.2 Operaes sobre listas usando posies contguas de memria... 204 B.3 Estrutura da lista usando apontadores ... . .......................................205 B.4 Operaes sobre listas usando apontadores .................................... 206 B.5 Campos do registro de um candidato ...............................................206 B.6 Primeiro refinamento do programa Vestibular ............................... 206 B.7 Segundo refinamento do programa Vestibular ............................... 207 B.8 Estrutura da lista ................................................................................ 208 B.9 Refinamento final do programa Vestibular .....................................209 B.10 Estrutura da pilha usando arranjo ....................................................209 B.11 Operaes sobre pilhas usando arranjos .........................................210 B.12 Estrutura da pilha usando apontadores ............................................ 210 B.13 Operaes sobre pilhas usando apontadores .................................. 211 B.14 Implementao do ET ....................................................................... 212 B.15 Procedimento Imprime utilizado no programa ET ........................ 213 B.16 Estrutura da fila usando arranjo ...................................................... 213 B.17 Operaes sobre filas usando posies contguas de memria .... 214 B.18 Estrutura da fila usando apontadores .............................................. 214 B.19 Operaes sobre filas usando apontadores .....................................215 C;1 Estrutura de um item do arquivo ....................................................... 217 C.2 Tipos utilizados na implementao dos algoritmos ....................... 217 C.3 Ordenao por seleo .......................................................................217 C.4 Ordenao por insero .....................................................................218 C.5 Algoritmo Shellsort ........................................................................... 218 C.6 Funo Partio ..................................................................................219 C.7 Funo Quicksort ............................................................................... 219 C.8 Funo para construir o heap ............................................................. 220 C.9 Funo Heapsort ................................................................................ 221 D.1 Estrutura do tipo dicionrio implementado como arranjo .............223

LISTA DE PROGRAMAS

D.2 Implementao das operaes usando arranjo ................................ 224 D.3 Pesquisa binria .................................................................................. 224 D.4 Estrutura do dicionrio .......................................................................225 D.5 Funo para pesquisar na rvore .......................................................225 D.6 Funo para inserir na rvore ............................................................226 D.7 Funo para inicializar .......................................................................226 D.8 Programa para criar a rvore .............................................................226 D.9 Funes para retirar x da rvore ....................................................... 227 D.10 Caminhamento central ......................................................................227 D.11 Estrutura do dicionrio para rvores SBB ..................................... 228 D.12 Procedimentos auxiliares para rvores SBB .................................. 229 D.13 Procedimento para inserir na rvore SBB ......................................230 D.14 Procedimento para inicializa a rvore SBB ................................... 231 D.15 Procedimento para retirar da rvore SBB ...................................... 234 D.16 Estrutura de dados ............................................................................ 234 D.17 Funes auxiliares ............................................................................ 235 D,18 Funo CrieNodos ............................................................................ 235 D.19 Algoritmo de pesquisa ......................................................................236 D.20 Inicializao da rvore ..................................................................... 236 D.21 Algoritmo de insero ...................................................................... 237 D.22 Implementao de funo de transformao ..................................238 D.23 Estrutura do dicionrio para listas encadeadas ..............................238 D.24 Operaes do dicionrio usando listas encadeadas .......................239 D.25 Estrutura do dicionrio usando open addressing .........................240 D.26 Operaes do dicionrio usando open addressing .......................241 E.1 Estrutura de dados para o sistema de paginao ............................. 243 E.2 Diferentes tipos de pginas para o sistema de paginao ...............243 E.3 Estrutura do dicionrio para rvore B .............................................. 244 E.4 Funo para inicializar uma vore B ................................................ 244 E.5 Funo para pesquisar na vore B .....................................................245 E.6 Primeiro refinamento do algoritmo Insere na rvore B .................. 246 E.7 Funo Insere Na Pgina ....................................................................246 E.8 Refinamento final do algoritmo Insere ............................................. 248 E.9 Funo Retira ...................................................................................... 250 E.10 Estrutura do dicionrio para rvore B* ...........................................251 E.11 Funo para pesquisar na rvore B* ............................................... 252

Captulo 1

Introduo1.1 Algoritmos, Estruturas de Dados e ProgramasOs algoritmos fazem parte do dia-a-dia das pessoas. As instrues para o uso de medicamentos, as indicaes de como montar um aparelho qualquer, uma receita de culinria so alguns exemplos de algoritmos. Um algoritmo pode ser visto como uma seqncia de aes executveis para a obteno de uma soluo para um determinado tipo de problema. Segundo Dijkstra (1971) um algoritmo corresponde a uma descrio de um padro de comportamento, expresso em termos de um conjunto finito de aes. Ao executarmos a operao a + b percebemos um mesmo padro de comportamento, mesmo que a operao seja realizada para valores diferentes de a e b. Estruturas de dados e algoritmos esto intimamente ligados. No se pode estudar estruturas de dados sem considerar os algoritmos associados a elas, assim como a escolha dos algoritmos em geral depende da representao e da estrutura dos dados. Para resolver um problema necessrio escolher uma abstrao da realidade, em geral atravs da definio de um conjunto de dados que representa a situao real. A seguir deve ser escolhida a forma de representar estes dados. A escolha da representao dos dados determinada, entre outras, pelas operaes a serem realizadas sobre os dados. Considere a operao de adio. Para pequenos nmeros uma boa representao atravs de barras verticais, caso em que a operao de adio bastante simples. J a representao atravs de dgitos decimais requer regras relativamente complicadas, as quais devem ser memorizadas. Entretanto, a situao se inverte quando consideramos a adio de grandes nmeros, sendo mais fcil a representao por dgitos decimais por causa do princpio baseado no peso relativo da posio de cada dgito.

1

2

CAPTULO 1. INTRODUO

Programar basicamente estruturar dados e construir algoritmos. De acordo com Wirth (1976, p.XII), programas so formulaes concretas de algoritmos abstratos, baseados em representaes e estruturas especficas de dados. Em outras palavras, programas representam uma classe especial de algoritmos capazes de serem seguidos por computadores. Entretanto, um computador s capaz de seguir programas em linguagem de mquina, que correspondem a uma seqncia de instrues obscuras e desconfortveis. Para contornar tal problema necessrio construir linguagens mais adequadas para facilitar a tarefa de programar um computador. Segundo Dijkstra (1976), uma linguagem de programao uma tcnica de notao para programar, com a inteno de servir de veculo tanto para a expresso do raciocnio algortmico quanto para a execuo automtica de um algoritmo por um computador.

1.2 Tipos de Dados e Tipos Abstratos de DadosEm linguagens de programao importante classificar constantes, variveis, expresses e funes de acordo com certas caractersticas, as quais indicam o seu tipo de dados. Este tipo deve caracterizar o conjunto de valores a que uma constante pertence, ou que podem ser assumidos por uma varivel ou expresso, ou que podem ser gerados por uma funo (Wirth, 1976, pp.440). Tipos simples de dados so grupos de valores indivisveis, como os tipos bsicos integer, boolean, char, e real do Pascal. Por exemplo, uma varivel do tipo boolean pode assumir ou o valor verdadeiro ou o valor falso, e nenhum outro valor. Os tipos estruturados em geral definem uma coleo de valores simples, ou um agregado de valores de tipos diferentes. A linguagem Pascal oferece uma grande variedade de tipos de dados, como ser mostrado na Seo 1.5. Um tipo abstrato de dados pode ser visto como um modelo matemtico, acompanhado das operaes definidas sobre o modelo. 0 conjunto dos inteiros acompanhado das operaes de adio, subtrao e multiplicao forma um exemplo de um tipo abstrato de dados. Aho, Hoperoft e Ullman ( 1983), utilizam extensivamente tipos abstratos de dados como base para o projeto de algoritmos. Nestes casos a implementao do algoritmo em uma linguagem de programao especfica exige que se encontre alguma forma de representar o tipo abstrato de dados, em termos dos tipos de dados e dos operadores suportados pela linguagem considerada. A representao do modelo matemtico por trs do tipo abstrato de dados realizada atravs de uma estrutura de dados. Tipos abstratos de dados podem ser considerados generalizaes de tipos primitivos de dados, da mesma forma que procedimentos so generalizaes de operaes. primitivas tais como adio, subtrao e multiplicao. Da

1.3. MEDIDA DO TEMPO DE EXECUO DE UM PROGRAMA

3

mesma forma que um procedimento usado para encapsular partes de um algoritmo, o tipo abstrato de dados pode ser usado para encapsular tipos de dados. Neste caso a definio do tipo e todas as operaes definidas sabre ele podem ser localizadas em uma nica seo do programa. Como exemplo, considere uma aplicao que utilize uma lista de inteiros. Poderamos definir um tipo abstrato de dados Lista, com as seguintes operaes sobre a lista: 1. faa a lista vazia, 2. obtenha o primeiro elemento da lista. Se a lista estiver vazia ento retorne nulo, 3. insira um elemento na lista. Existem vrias opes de estruturas de dados que permitem uma implementao eficiente para listas. Uma possvel implementao para o tipo abstrato de dados Lista atravs do tipo estruturado arranjo. A seguir cada operao do tipo abstrato de dados implementada como um procedimento na linguagem de programao escolhida. Se existe necessidade de alterar a implementao do tipo abstrato de dados, a alterao fica restrita parte encapsulada, sem causar impactos em outras partes do cdigo.. Cabe ressaltar que cada conjunto diferente de operaes define um tipo abstrato de dados diferente, mesmo que todos os conjuntos de operaes atuem sobre um mesmo modelo matemtico. Uma razo forte para isto que a escolha adequada de uma implementao depende fortemente das operaes a serem realizadas sobre o modelo.

1.3 Medida do Tempo de Execuo de um Programa0 projeto de algoritmos fortemente influenciado pelo estudo de seus comportamentos. Depois que um problema analisado e decises de projeto so finalizadas, o algoritmo tem que ser implementado em um computador. Neste momento o projetista tem que estudar as vrias opes de algoritmos a serem utilizados, onde os aspectos de tempo de execuo e espao ocupado so consideraes importantes. Muitos destes algoritmos so encontrados em reas tais como pesquisa operacional, otimizao, teoria dos grafos, estatstica, probabilidades, entre outras. Na rea de anlise de algoritmos, existem dois tipos de problemas bem distintos, conforme apontou Knuth (1971): (i) Anlise de um algoritmo particular. Qual o custo de usar um dado algoritmo para resolver um problema especfico? Neste caso, caractersticas

4

CAPTULO 4. INTRODUO

importantes do algoritmo em questo devem ser investigadas, geralmente uma anlise do nmero de vezes que cada parte do algoritmo deve ser executada, seguida do estudo da quantidade de memria necessria. (ii) Anlise de uma classe de algoritmos. Qual o algoritmo de menor custo possvel para resolver um problema particular? Neste caso, toda uma famlia de algoritmos para resolver um problema especfico investigada com o objetivo de identificar um que seja o melhor possvel. Isto significa colocar limites para a complexidade computacional dos algoritmos pertencentes classe. Por exemplo, possvel estimar o nmero mnimo de comparaes necessrias para ordenar n nmeros atravs de comparaes sucessivas, conforme veremos mais adiante no Captulo 3. Quando conseguimos determinar o menor custo possvel para resolver problemas de uma determinada classe, como no caso de ordenao, temos a medida da dificuldade inerente para resolver tais problemas. Ainda mais, quando o custo de um algoritmo igual ao menor custo possvel, ento podemos concluir que o algoritmo timo para a medida de custo considerada. Em muitas situaes podem existir vrios algoritmos para resolver o mesmo problema, sendo pois necessrio escolher aquele que o melhor. Se uma mesma medida de custo aplicada a diferentes algoritmos ento possvel compar-los e escolher o mais adequado para resolver o problema em questo. O custo de utilizao de um algoritmo pode ser medido de vrias maneiras. Uma delas atravs da execuo do programa em um computador real, sendo o tempo de execuo medido diretamente. As medidas de tempo obtidas desta forma so bastante inadequadas e os resultados jamais devem ser generalizados. As principais objees so: (i) os resultados so dependentes do compilador que pode favorecer algumas construes em detrimento de outras; (ii) os resultados dependem do hardware; (iii) quando grandes quantidades de memria so utilizadas, as medidas de tempo podem depender deste aspecto. Apesar disso, Gonnet e Baeza-Yates (1991, p.7) apresentam argumentos a favor de se obter medidas reais de tempo para algumas situaes particulares como, por exemplo, quando existem vrios algoritmos distintos para resolver um mesmo tipo de problema, todos com um custo de execuo dentro de uma mesma ordem de grandeza. Assim os custos reais das operaes so todos considerados, assim como os custos no aparentes tais como alocao de memria, indexao, carga, etc. Uma forma mais adequada de se medir o custo de utilizao de um algoritmo atravs do uso de um modelo matemtico, baseado em um computador idealizado como, por exemplo, o computador MIX proposto por Knuth ( 1968). 0 conjunto de operaes a serem executadas deve ser especificado, assim como o custo associado com a execuo de cada operao. Mais usual ainda ignorar o custo de algumas das operaes envolvidas e considerar apenas as operaes mais significativas. Por exemplo, para algoritmos de

1.3. MEDIDA DO TEMPO DE EXECUO DE UM PROGRAMA 5

6

CAPTULO 1. INTRODUO

A medida do custo de execuo de um algoritmo depende principalmente do tamanho da entrada dos dados. Por isso comum considerar-se o tempo de execuo de um programa como uma funo do tamanho da entrada. Entretanto, para alguns algoritmos, o custo de execuo uma funo da entrada particular dos dados, no apenas do tamanho da entrada. No caso da funo Max do Programa 1.1 o algoritmo possui a propriedade de que o custo uniforme sobre todos os problemas de tamanho n. J para um algoritmo de ordenao isto no ocorre: se os dados de entrada j estiverem quase ordenados ento o algoritmo pode ter que trabalhar menos. Temos ento que distinguir trs cenrios: melhor caso, pior caso e caso mdio. 0 melhor caso corresponde ao menor tempo de execuo sobre todas as possveis entradas de tamanho n. 0 pior caso corresponde ao maior tempo de execuo sobre todas as entradas de tamanho n . Se f uma funo de complexidade baseada na anlise de pior caso ento o custo de aplicar o algoritmo nunca. maior do que (n). 0 caso mdio (ou caso esperado) corresponde mdia dos tempos de execuo de todas as entradas de tamanho n. Na anlise do caso esperado, uma distribuio de probabilidades sobre o conjunto de entradas de tamanho n suposta, e o custo mdio obtido com base nesta distribuio. Por esta razo, a anlise do caso mdio geralmente muito mais difcil de obter do que as anlises do melhor e do pior caso. comum supor uma distribuio de probabilidades em que todas as entradas possveis so igualmente provveis. Entretanto, na prtica isto nem sempre verdade. Por isso a anlise do caso esperado dos algoritmos a serem estudados s ser apresentada quando esta fizer sentido. Para ilustrar estes conceitos considere o problema de acessar os registros de um arquivo. Cada registro contm uma chave nica que utilizada para recuperar registros do arquivo. Dada uma chave qualquer o problema consiste em localizar o registro que contenha esta chave. 0 algoritmo de pesquisa mais simples que existe o que faz uma pesquisa seqencial. Este algoritmo examina os registros na ordem em que eles aparecem no arquivo, at que o registro procurado seja encontrado ou fique determinado que o mesmo no se encontra no arquivo. Seja f uma funo de complexidade tal que (n) o nmero de registros consultados no arquivo, isto , o nmero de vezes que a chave de consulta comparada com a chave de cada registro. Os casos a considerar so: melhor caso : (n) = 1 pior caso : (n) = n caso mdio :(n) = (n + 1)/2 0 melhor caso ocorre quando o registro procurado o primeiro consultado. 0 pior caso ocorre quando o registro procurado o ltimo consultado,

1.3. MEDIDA DO TEMPO DE EXECUO DE UM PROGRAMA 7

8

CAPTULO 1. I N T R O D U O

1.3. MEDIDA DO TEMPO DE EXECUO DE UM PROGRAMA 9

10

CAPTULO 1. INTRODUO

A Tabela 1.1 apresenta uma comparao entre os algoritmos dos Programas 1.2, 1.3 e 1.4,. considerando o nmero de comparaes como medida de complexidade. Os algoritmos MaxMin2 e MaxMin3 so superiores ao algoritmo MaxMinl de forma geral. O algoritmo MaxMin3 superior ao algoritmo MaxMin2 com relao ao pior caso e bastante prximo quanto ao caso mdio.Os Trs Algoritmos MaxMin1 MaxMin2 MaxMin3 f (n) Melhor caso 2(n-1) n1 3n/2-2 Pior caso 2(n-1) 2(n-1) 3n/2-2 Caso mdio 2(n-1) 3n/2-3/2 3n/2-2

Tabela 1.1:

Comparao dos algoritmos para obter o mximo e o mnimo

Considerando novamente o nmero de comparaes realizadas, existe possibilidade de obter um algoritmo mais eficiente para este problema? Para responder a esta questo necessrio conhecer o limite inferior para a classe de algoritmos para obter o maior e o menor elemento de um conjunto. Uma tcnica muito utilizada para obter o limite inferior para uma classe qualquer de algoritmos atravs da utilizao de um orculo.2 Dado um modelo de computao que expresse o comportamento do algoritmo o orculo informa o resultado de cada passo possvel, que no nosso caso seria o resultado de cada comparao. Para derivar o limite inferior o orculo procura sempre fazer com que o algoritmo trabalhe o mximo, escolhendo como resultado da prxima comparao aquele que cause o maior trabalho possvel que necessrio para determinar a resposta final. O teorema abaixo, apresentado por Horowitz e Sahni (1978, p.476), utiliza um orculo para derivar o limite inferior no nmero de comparaes necessrias para obter o mximo e o mnimo de um conjunto com n elementos. Teorema: Qualquer algoritmo para encontrar o maior elemento e o menor elemento de um conjunto com n elementos no ordenados, n 1, faz pelo menos [3n/2] 2 comparaes. Prova: A tcnica utilizada define um orculo que descreve o comportamento do algoritmo atravs de um conjunto de ntuplas, mais um conjunto de regras associadas que mostram as tuplas possveis (estados) que um algoritmo pode assumir a partir de uma dada tupla e uma nica comparao.

2De acordo com o Novo Dicionrio Aurlio da Lingua Portuguesa, um orculo : 1. Resposta de um deus a quem o consultava. 2. Divindade que responde consultas e orienta o crente: o orculo de Delfos. 3. Fig. Palavra, sentena ou deciso inspirada, infalvel ou que tem grande autoridade: os orculos dos profetas, os orculos da cincia.

1.3. MEDIDA DO TEMPO DE EXECUO DE UM PROGRAMA 11 O comportamento do algoritmo pode ser descrito por uma 4-tupla, representada por (a, b, c, d), onde a representa o nmero de elementos que nunca foram comparados; b representa o nmero de elementos que foram vencedores e nunca perderam em comparaes realizadas; c representa o nmero de elementos que foram perdedores e nunca venceram em comparaes realizadas; d representa o nmero de elementos que foram vencedores e perdedores em comparaes realizadas. O algoritmo inicia no estado (n, 0, 0, 0) e termina com (0, 1,1, n 2). Desta forma, aps cada comparao a tupla (a, b, c, d) consegue progredir apenas se ela assume um dentre os cinco estados possveis, a saber:

1.3.1 Comportamento Assinttico de FunesComo j foi observado anteriormente, o custo para obter uma soluo para um dado problema aumenta cem o tamanho n do problema. O nmero de comparaes para encontrar o maior elemento de um conjunto de n inteiros, ou para ordenar os elementos de um conjunto com n elementos, aumenta com n: 0 parmetro n fornece uma medida da dificuldade para se resolver

12

CAPITULO 1. INTRODUO

o problema, no sentido de que o tempo necessrio para resolver o problema cresce quando n cresce. Para valores suficientemente pequenos de n, qualquer algoritmo custa pouco para ser executado, mesmo os algoritmos ineficientes. Em outras palavras, a escolha do algoritmo no um problema crtico para problemas de tamanho pequeno. Logo, a anlise de algoritmos realizada para valores grandes de n. Para tal considera-se o comportamento de suas funes de custo para valores grandes de n, isto , estuda-se o comportamento assinttico das funes de custo. O comportamento assinttico de(n) representa o limite do comportamento do custo quando n cresce. A anlise de um algoritmo geralmente conta apenas algumas operaes elementares e, em muitos casos, apenas uma operao elementar. A medida de custo ou medida de complexidade relata o crescimento assinttico da operao considerada. A definio seguinte relaciona o comportamento assinttico de duas funes distintas.

1.3. MEDIDA DO TEMPO DE EXECUO DE UM PROGRAMA 13

14

CAPTULO 1. INTRODUO

1.3.2 Classes de Comportamento AssintticoSe f uma funo de complexidade para um algoritmo F , ento 0 ( f ) considerada a complexidade assinttica ou o comportamento assinttico do algoritmo F . Igualmente, se g uma funo para um algoritmo G, ento 0 ( g ) considerada a complexidade assinttica do algoritmo G. A relao de dominao assinttica permite comparar funes de complexidade. Entretanto, se as funes f e g dominam assintoticamente uma a outra ento os algoritmos associados so equivalentes. Nestes casos, o comportamento assinttico no serve para comparar os algoritmos. Por exemplo, dois algoritmos F e G aplicados mesma classe de problemas, sendo que F leva trs vezes o tempo de G ao serem executados, isto (n ) = 3 g ( n ) , sendo que 0 ( f ( n ) ) = 0 ( g ( n ) ) . Logo o comportamento assinttico no serve para comparar os algoritmos F e G porque eles diferem apenas por uma constante. Programas podem ser avaliados atravs da comparao de suas funes de complexidade, negligenciando as constantes de proporcionalidade. Um programa com tempo de execuo 0 ( n ) melhor que um programa com tempo de execuo 0 ( n 2) . Entretanto, as constantes de proporcionalidade em cada caso podem alterar esta considerao. Por exemplo, possvel que um programa leve 100n unidades de tempo para ser executado enquanto um outro leve 2 n 2 unidades de tempo. Qual dos dois programas melhor? A resposta a esta pergunta depende do tamanho do problema a ser executado. Para problemas de tamanho n < 50, o programa com tempo de execuo 2 n 2 melhor do que o programa com tempo de execuo 100n. Para problemas com entrada de dados pequena prefervel usar o programa cujo tempo de execuo 0 ( n 2) . Entretanto, quando n cresce, o programa com tempo 0 ( n 2) leva muito mais tempo que o programa 0(n).

1.3. MEDIDA DO TEMPO DE EXECUO DE UM PROGRAMA 15 A maioria dos algoritmos possui um parmetro que afeta o tempo de execuo de forma mais significativa, usualmente o nmero de itens a ser processado. Este parmetro pode ser o nmero de registros de um arquivo a ser ordenado, ou o nmero de ns de um grafo. As principais classes de problemas possuem as funes de complexidade descritas abaixo. 1 . f (n) = 0(1). Algoritmos de complexidade 0(1) so ditos de complexidade constante. O uso do algoritmo independe do tamanho de n. Neste caso as instrues do algoritmo so executadas um nmero fixo de vezes. 2 . ( n ) = O(log n). Um algoritmo de complexidade O( logn) dito ter complexidade logartmica. Este tempo de execuo ocorre tipicamente em algoritmos que resolvem um problema transformando-o em problemas menores. Nestes casos, o tempo de execuo pode ser considerado como sendo menor do que uma constante grande. Quando n mil e a base do logaritmo 2, log2n 10, quando n um milho, log2n 20. Para dobrar o valor de log n temos que considerar o quadrado de n. A base do logaritmo muda pouco estes valores: quando n um milho, o log2n 20 e o log10n 6. 3. f (n) = 0(n). Um algoritmo de complexidade 0(n) dito ter complexidade linear. Em geral um pequeno trabalho realizado sobre cada elemento de entrada. Esta a melhor situao possvel para um algoritmo que tem que processar n elementos de entrada ou produzir n elementos de sada. Cada vez que n dobra de tamanho o tempo de execuo dobra. 4 . f ( n ) = O ( n log n ) . Este tempo de execuo ocorre tipicamente em algoritmos que resolvem um problema quebrando-o em problemas menores, resolvendo cada um deles independentemente e depois ajuntando as solues. Quando n um milho e a base do logaritmo 2, nlog2n cerca de 20 milhes. Quando n dois milhes, nlog2n cerca de 42 milhes, pouco mais do que o dobro. 5 . f (n) = 0(n2). Um algoritmo de complexidade 0(n2) dito ter complexidade quadrtica. Algoritmos desta ordem de complexidade ocorrem quando os itens de dados so processados aos pares, muitas vezes em um anel dentro de outro. Quando n mil, o nmero de operaes da ordem de 1 milho. Sempre que n dobra o tempo de execuo multiplicado por 4. Algoritmos deste tipo so teis para resolver problemas de tamanhos relativamente pequenos. 6 . f (n) = 0(n3). Um algoritmo de complexidade 0(n3) dito ter complexidade cbica. Algoritmos desta ordem de complexidade so teis

16

CAPITULO 1. INTRODUOapenas para resolver pequenos problemas. Quando n cem, o nmero de operaes da ordem de 1 milho. Sempre que n dobra o tempo de execuo fica multiplicado por 8.

7. (n) = 0(2n). Um algoritmo de complexidade 0(2n) dito ter complexidade exponencial. Algoritmos desta ordem de complexidade geralmente no so teis sob o ponto de vista prtico. Eles ocorrem na soluo de problemas quando se usa fora bruta para resolv-los. Quando n vinte, o tempo de execuo cerca de um milho. Quando n dobra, o tempo de execuo fica elevado ao quadrado. Para ilustrar melhor a diferena entre as classes de comportamento assinttico Garey e Johnson (1979, p.7) apresentam o quadro mostrado na Ta-bela 1.2. Este quadro mostra a razo de crescimento de vrias funes de complexidade para tamanhos diferentes de n, onde cada funo expressa o tempo de execuo em microsegundos. Um algoritmo linear executa em um segundo um milho de operaes.

T a b e l a 1.2: Comparao de virias funes de complexidade

Um outro aspecto interessante o efeito causado pelo aumento da velocidade dos computadores sobre os algoritmos com as funes de complexidade citadas acima. A Tabela 1.3 mostra como um aumento de 100 ou de 1000 vezes na velocidade de computao de um computador atual influi na soluo do maior problema possvel de ser resolvido em uma hora. Note que um aumento de 1000 vezes na velocidade de computao resolve um problema dez vezes maior para um algoritmo de complexidade 0(n3 ), enquanto um algoritmo de complexidade 0(2n) apenas adiciona dez ao tamanho do maior problema possvel de ser resolvido em uma hora.

1.3. MEDIDA DO TEMPO DE EXECUO DE UM PROGRAMA 17Funo de custo de de tempo n n2 n3 2n Computador atual tl t2 t3 t4 Computador 100 vezes mais rpido 100t 1 10t 2 4,6t 3 t 4+ 6 , 6 Computador 1000 vezes mais rpido 1000t 1 31, 6t 2 10t 3 t4+10

Tabela 1.3: Influncia do aumento de velocidade dos computadores no tamanho t do problema

Um algoritmo cuja funo de complexidade O(c n), c > 1, chamado de algoritmo exponencial no tempo de execuo. Um algoritmo cuja funo de complexidade O(p(n)), onde p(n) um polinmio, chamado de algoritmo polinomial no tempo de execuo. A distino entre estes dois tipos de algoritmos torna-se significativa quando o tamanho do problema a ser resolvido cresce, conforme ilustra a Tabela 1.2. Esta a razo por que algoritmos polinomiais so muito mais teis na prtica do que algoritmos exponenciais. Os algoritmos exponenciais so geralmente simples variaes de pesquisa exaustiva, enquanto algoritmos polinomiais so geralmente obtidos atravs de um entendimento mais profundo da estrutura do problema. Um problema considerado intratvel se ele to difcil que no existe um algoritmo polinomial para resolv-lo, enquanto um problema considerado bem resolvido quando existe um algoritmo polinomial para resolv-lo. Entretanto, a distino entre algoritmos polinomiais eficientes e algoritmos exponenciais ineficientes possui vrias excees. Por exemplo, um algoritmo com funo de complexidade n) = 2n mais rpido que um algoritmo g(n) = n 5 para valores de n menores ou iguais a 20. Da mesma forma, existem algoritmos exponenciais que so muito teis na prtica. Por exemplo, o algoritmo Simplex para programao linear possui complexidade de tempo exponencial para o pior caso (Garey e Johnson, 1979), mas executa muito rpido na prtica. Infelizmente, exemplos como o do algoritmo Simplex no ocorrem com freqncia na prtica, e muitos algoritmos exponenciais conhecidos no so muito teis. Considere, como exemplo, o seguinte problema: um caixeiro viajante deseja visitar n cidades de tal forma que sua viagem inicie e ter-mine em uma mesma cidade, e cada cidade deve ser visitada uma nica vez. Supondo que sempre exista uma estrada entre duas cidades quaisquer, o problema encontrar a menor rota que o caixeiro viajante possa utilizar na sua viagem. A Figura 1.4 ilustra o exemplo acima para quatro cidades cl, c2, c3,c4, onde os nmeros nos arcos indicam a distncia entre duas cidades. O per-

18

CAPT ULO 1. INTRODUO

curso < c1, c3, c4, c2, c1 > uma soluo para o problema, cujo percurso total tem distncia 24. Um algoritmo simples para o problema acima seria verificar todas as rotas e escolher a menor delas. Como existem ( n 1)! rotas possveis e a distncia total percorrida em cada rota envolve n adies, ento o nmero total de adies n ! . Para o exemplo da Figura 1.4 teriamos 24 adies. Suponha agora 50 cidades: o nmero de adies seria igual ao fatorial de 50, que aproximadamente 1064. Considerando um computador capaz de executar 109 adies por segundo, o tempo total para resolver o problema com 50 cidades seria maior do que 1045 sculos somente para executar as adies.

Figura 1.4: Problema do caixeiro viajante

1.4 Tcnicas de Anlise de AlgoritmosA determinao do tempo de execuo de um programa qualquer pode se tornar um problema matemtico complexo quando se deseja determinar o valor exato da funo de complexidade. Entretanto, a determinao da ordem do tempo de execuo de um programa, sem haver preocupao com o valor da constante envolvida, pode ser uma tarefa mais simples. E mais fcil determinar que o nmero esperado de comparaes para recuperar um registro de um arquivo utilizando pesquisa seqencial 0 ( n ) do que efetivamente determinar que este nmero ( n + 1)/2, quando cada registro tem a mesma probabilidade de ser procurado. A anlise de algoritmos ou programas utiliza tcnicas de matemtica discreta, envolvendo contagem ou enumerao dos elementos de um conjunto que possuam uma propriedade comum. Estas tcnicas envolvem a manipulao de somas, produtos, permutaes, fatoriais, coeficientes binomiais, soluo de equaes de recorrncia, entre outras. Algumas destas tcnicas sero ilustradas informalmente atravs de exemplos.

1.4. TCNICAS DE ANLISE DE ALGORITMOS

19

Infelizmente no existe um conjunto completo de regras para analisar programas. Aho, Hoperoft e Ullman (1983) enumeram alguns princpios a serem seguidos. Muitos destes princpios utilizam as propriedades sobre a notao O apresentadas na Figura 1.3. So eles: 1. 0 tempo de execuo de um comando de atribuio, de leitura ou de escrita pode ser considerado como 0(1). Existem excees para as linguagens que permitem a chamada de funes em comandos de atribuio, ou quando atribuies envolvem vetores de tamanho arbitrariamente grandes. 2. 0 tempo de execuo de uma seqncia de comandos determinado pelo maior tempo de execuo de qualquer comando da seqncia. 3. 0 tempo de execuo de um comando de deciso composto pelo tempo de execuo dos comandos executados dentro do comando condicional, mais o tempo para avaliar a condio, que 0(1). 4. 0 tempo para executar um anel a soma do tempo de execuo do corpo do anel mais o tempo de avaliar a condio para terminao, multiplicado pelo nmero de iteraes do anel. Geralmente o tempo para avaliar a condio para terminao 0(1). 5. Quando o programa possui procedimentos no recursivos, o tempo de execuo de cada procedimento deve ser computado separadamente um a um, iniciando com os procedimentos que no chamam outros procedimentos. A seguir devem ser avaliados os procedimentos que chamam os procedimentos que no chamam outros procedimentos, utilizando os tempos dos procedimentos j avaliados. Este processo repetido at chegar no programa principal. 6. Quando o programa possui procedimentos recursivos, para cada procedimento associada uma funo de complexidade f (n) desconhecida, onde n mede o tamanho dos argumentos para o procedimento, conforme ser mostrado mais adiante. Com o propsito de ilustrar os vrios conceitos apresentados acima, vamos apresentar alguns programas e, para cada um deles, mostrar com detalhes os passos envolvidos em sua anlise. Exemplo: Considere o algoritmo para ordenar os n elementos de um conjunto A, cujo princpio o seguinte: 1. Selecione o menor elemento do conjunto 2. Troque este elemento com o primeiro elemento A[1].

20

CAPTULO 1. INTRODUO

1.4. T C N I C A S D E A N L I S E D E A L G O R I T M O S

21

22

CAPITULO 1. INTRODUO

1.4. TCNICAS DE ANLISE DE ALGORITMOS

23

24

CAPTULO 1. INTRODUO

1.5. PASCAL

25

1.5 PascalOs programas apresentados neste livro usam apenas as caractersticas bsicas do Pascal, de acordo com a definio apresentada por Jensen e Wirth (1974). Sempre que possvel so evitadas as facilidades mais avanadas disponveis em algumas implementaes do Pascal. 0 objetivo desta seo no apresentar a linguagem Pascal na sua totalidade, mas apenas examinar algumas de suas caractersticas, facilitando assim a leitura deste livro para as pessoas pouco familiarizadas com a lingua -gem. Uma descrio clara e- concisa da linguagem apresentada por Cooper (1983). Um bom texto introdutrio sobre a linguagem apresentado por Clancy e Cooper (1982). As vrias partes componentes de um programa Pascal podem ser vistas na Figura 1.5. Um programa Pascal comea com um cabealho que d nome ao programa. Rtulos, constantes, tipos, variveis, procedimentos, e funes so declaradas sempre na ordem indicada pela Figura 1.5. A parte ativa do programa descrita como uma seqncia de comandos, os quais incluem chamadas de procedimentos e funes.

program label const type var procedure ou function begin . . . end

cabealho do programa declarao de rtulo para goto definio de constantes definio de tipos de dados declarao de variveis declarao de subprogramas

comandos do programa

F i g u r a 1.5: Estrutura de um programa Pascal

A regra geral para a linguagem Pascal tornar explcito o tipo associado quando se declara uma constante, varivel ou funo, o que. permite testes de consistncia durante o tempo de compilao. A definio de tipos permite ao programador alterar o nome de tipos existentes, como tambm criar um nmero ilimitado de outros tipos. No caso do Pascal os tipos podem ser colocados em trs categorias: simples, estruturados, e apontadores. Tipos simples so grupos de valores indivisveis, estando dentro desta categoria os tipos bsicos integer, boolean, char, e real. Tipos simples adicionais podem ser enumerados atravs de uma listagem de novos grupos de

26

CAPTULO 1. INTRODUO

valores, ou atravs da indicao de subintervalos que restringem tipos a uma subseqncia dos valores de um outro tipo simples previamente definido. Exemplos de tipos enumerados type cor type sexo type boolean = (vermelho, azul, rosa); = (mas, fern); = (false, true);

Se as variveis c, s, e d so declaradas var c cor; var s sexo; var b boolean; : : :

ento so possveis as seguintes atribuies c : =rosa; s : =fern; b : =true; Exemplos de tipos com subintervalos type ano = 1999; type letra 'A'..'Z'; Dadas as variveis vara : ano; var b : letra; 1900.. =

1.5. PASCALonde a constante n deve ser previamente declarada const n = 20; Dada a varivel var x : coluna;

27

as atribuies x[1]:=0.75, x[2]:=0.85 e x[3]:=1.5 so possveis. Um tipo estruturado registro uma unio de valores de tipos quaisquer, cujos campos podem ser acessados pelos seus nomes. Exemplos: type data = record dia : 1..31; ms : 1..12; end; type pessoa = record sobrenome alfa; primeironome alfa; aniversrio data; sexo end; Declarada a varivel var p: pessoa; valores particulares podem ser atribuidos como se segue p.sobrenome p.primeironome p.aniversrio.dia p.aniversrio.ms p.sexo := := := := :='Ziviani';

: : : : (mas, ferm);

'Patricia'; 21; 10; fern;

A Figura 1.6 ilustra este exemplo. Um tipo estruturado conjunto define a coleo de todos os subconjuntos de algum tipo simples, com operadores especiais * (interseo), + (unio), (diferena) e in (pertence a) definidos para todos os tipos conjuntos. Exemplos: type conjint = set of 1..9; type conjcor = set of cor; type conjchar = set of char;

28

CAPTULO 1. INTRODUO

1.5. PASCAL

29

Programa 1.8: Programa para copiar arquivo

O Programa 1.8 copia o contedo arquivo Velho no arquivo Novo. Observe que os nomes dos arquivos aparecem como parmetros do programa. E importante observar que a atribuio de nomes de arquivos externos, ao programa varia de compilador para compilador. Por exempla, no caso do Turbo Pascal3 a atribuio do nome externo de um arquivo a uma varivel interna ao programa realizada atravs do comando assign e no como parmetros do programa. Os tipos apontadores so teis para criar estruturas de dados encadeadas, do tipo listas, rvores, e grafos. Um apontador uma varivel que referencia uma outra varivel alocada dinamicamente. Em geral a varivel referenciada definida como um registro que inclui tambm um apontador para outro elemento do mesmo tipo. Exemplo: type Apontador = ^Nodo; type Nodo = record Chave : integer Apont : Apontador; end; Dada uma varivel3 Turbo

Pascal marca registrada da Borland International

30 var Lista: Apontador;

CAPTULO 1. INTRODUO

possvel criar uma lista como ilustrada na Figura 1.7.

Figura 1.7: Lista encadeada

Notas BibliogrficasEstudos bsicos sobre os conceitos de algoritmos, estruturas de dados e programas podem ser encontrados em Dahl, Dijkstra e Hoare (1972), Dijkstra ( 1971), Dijkstra (1976), Hoare (1969), Wirth (1971), Wirth (1974), Wirth ( 1976). Mais recentemente Manber (1988) e Manber (1989) tratam da utilizao de induo matemtica para o projeto de algoritmos. A anlise assinttica de algoritmos hoje a principal medida de eficincia para algoritmos. Existem muitos livros que apresentam tcnicas para analisar algoritmos, tais como somatrios, equaes de recorrncia, rvores de deciso, orculos, dentre outras. Knuth (1968), Knuth (1973), Knuth (1981), Graham, Knuth e Patashnik (1989), Aho, Hoperoft e Ullman (1974), Stanat e McAllister (1977), Cormem, Leiserson e Rivest (1990), Manber (1989), Horowitz e Sahni (1978), Greene e Knuth (1982), so alguns exemplos. Artigos gerais sobre o tpico incluem Knuth (1971), Knuth (1976), Weide (1977), Lueker (1980), Flajolet e Vitter (1987). Tarjan (1985) apresenta custo amortizado: se certa parte de um algoritmo executada muitas vezes, cada vez com um tempo de execuo diferente, ao invs de considerar o pior caso em cada execuo, os diferentes custos so amortizados. Existe uma enorme quantidade de livros sobre a linguagem Pascal. O Pascal padro foi definido originalmente em Jensen e Wirth (1974). O livro de Cooper (1983) apresenta uma descrio precisa e ao mesmo tempo didtica do Pascal padro. Exerccios 1) D o conceito de algoritmo

EXERCCIOS

31

32

CAPTULO 1. INTRODUO

EXERCCIOS

33

34

CAPITULO 1. INTRODUO

12) Apresente um algoritmo para obter o maior e o segundo maior elemento de um conjunto. Apresente tambm uma anlise do algoritmo. Voc acha o seu algoritmo eficiente? Por qu? Procure comprovar suas respostas. 13) So dados 2n nmeros distintos distribuidos em dois arranjos com n elementos A e B ordenados de maneira tal que (Carvalho, 1992): A[1] > A[2] > A[3] > > A[n] e B[1] > B[2] > B[3] > > B[n]. O problema achar o n-simo maior nmero dentre estes 2n elementos. a) Obtenha um limite inferior para o nmero de comparaes necessrias para resolver este problema. b) Apresente um algoritmo cuja complexidade no pior caso seja iqual ao valor obtido na letra a), ou seja, um algoritmo timo.

Captulo 2

Estruturas de Dados Bsicas2.1 Listas LinearesUma das formas mais simples de interligar os elementos de um conjunto atravs de uma lista. Lista uma estrutura onde as operaes inserir, retirar e localizar so definidas. Listas so estruturas muito flexveis porque podem crescer ou diminuir de tamanho durante a execuo de um programa, de acordo com a demanda. Itens podem ser acessados, inseridos ou retirados de uma lista. Duas listas podem ser concatenadas para formar uma lista nica, assim como uma lista pode ser partida em duas ou mais listas. Listas so adequadas para aplicaes onde no possvel prever a demanda por memria, permitindo a manipulao de quantidades imprevisveis de dados, de formato tambm imprevisvel. Listas so teis em aplicaes tais como manipulao simblica, gerncia de memria, simulao e compiladores. Na manipulao simblica os termos de uma frmula podem crescer sem limites. Em simulao dirigida por relgio pode ser criado um nmero imprevisvel de processos, os quais tm que ser escalonados para execuo de acordo com alguma ordem predefinida. Uma lista linear uma seqncia de zero ou mais itens x1, x2,,xn, onde xi de um determinado tipo e n representa o tamanho da lista linear. Sua principal propriedade estrutural envolve as posies relativas dos itens em uma dimenso. Assumindo n 1, xy1 o primeiro item da lista e xn o ltimo item da lista. Em geral xi precede xi+1 para i = 1, 2, ,n 1, e xi sucede xa_1 para i = 2, 3, , n. Em outras palavras, o elemento xi dito estar na i-sima posio da lista. Para criar um tipo abstrato de dados Lista, necessrio definir um conjunto de operaes sobre os objetos do tipo Lista. 0 conjunto de operaes a ser definido depende de cada aplicao, no existindo um conjunto de operaes que seja adequado a todas as aplicaes. Um conjunto 35

36

CAPTULO 36. ESTRUTURAS DE DADOS BSICAS

de operaes necessrio a uma maioria de aplicaes apresentado a seguir. Outras sugestes para o conjunto de operaes podem ser encontradas em Knuth (1968, p.235) e Aho, Hoperoft e Ullman (1983, pp.38-39). 1. Criar uma lista linear vazia. 2. Inserir um novo item imediatamente aps o i-simo item. 3. Retirar o i-simo item. 4. Localizar o i-simo item para examinar e/ou alterar o contedo de seus componentes. 5. Combinar duas ou mais listas lineares em uma lista nica. 6. Partir uma lista linear em duas ou mais listas. 7. Fazer uma cpia da lista linear. 8. Ordenar os itens da lista em ordem ascendente ou descendente, de acordo com alguns de seus componentes. 9. Pesquisar a ocorrncia de um item com um valor particular em algum componente. 0 item 8 acima objeto de um estudo cuidadoso no Captulo 3, e o item 9 ser tratado nos Captulos 4 e 5. Um conjunto de operaes necessrio para uma aplicao exemplo a ser apresentada mais adiante apresentado a seguir. 1. FLVazia(Lista). Faz a lista ficar vazia. 2. Insere(x, Lista). Insere x aps o ltimo item da lista. 3. Retira(p, Lista, x). Retorna o item x que est na posio p da lista, retirando-o da lista e deslocando os itens a partir da posio p+l para as posies anteriores. 4. Vazia(Lista). Esta funo retorna true se a lista est vazia; seno retorna false. 5. Imprime(Lista). Imprime os itens da lista na ordem de ocorrncia. Existem vrias estruturas de dados que podem ser usadas para representar listas lineares, cada uma com vantagens e desvantagens particulares. As duas representaes mais utilizadas so as implementaes atravs de arranjos e de apontadores. A implementao atravs de cursores (Aho, Hoperoft e Ullman, 1983, pp. 48) pode ser til em algumas aplicaes.

2.37. LISTAS LINEARES

37

2.1.1 Implementao de Listas A t r a v s de ArranjosEm um tipo estruturado arranjo, os itens da lista so armazenados em posies contguas de memria, conforme ilustra a Figura 2.1. Neste caso a lista pode ser percorrida em qualquer direo. A insero de um novo item pode ser realizada aps o ltimo item com custo constante. A insero de um novo item no meio da lista requer um deslocamento de todos os itens localizados aps o ponto de insero. Da mesma forma, retirar um item do incio da lista requer um deslocamento de itens para preencher o espao deixado vazio.

Figura 2.1: Implementao de uma lista atravs de arranjo

O campo Item o principal componente do registro TipoLista mostrado no Programa 2.1. Os itens so armazenados em um array de tamanho suficiente para armazenar a lista. 0 campo Ultimo do registro TipoLista contm um apontador para a posio seguinte a do ltimo elemento da lista. 0 i-simo item da lista est armazenado na i-sima posio do array, 1 < i c[2i] c[i] > c[2i + 1] para todo i = 1, 2, ... , n / 2 . Esta ordem pode ser facilmente visualizada se a seqncia de chaves for desenhada em uma rvore binria, onde as linhas que saem de uma chave levam a duas chaves menores no nvel inferior, conforme ilustra a Figura. 3.6. Esta estrutura conhecida como uma rvore binria completa1: o primeiro nodo chamado raiz, os nodos abaixo de cada nodo so chamados nodos filhos, e o nodo acima de cada nodo chamado nodo pai. Um estudo mais detalhado de rvores ser apresentado no Captulo 4. Observe que as chaves na rvore da Figura 3.6 satisfazem a condio do heap: a chave em cada nodo maior do que as chaves em seus filhos, se eles existirem. Conseqentemente, a chave no nodo raiz a maior chave do conjunto.' Uma rvore binria completa uma rvore binria com os nodos numerados de 1 a n, onde o nodo Lk/2 j o pai do nodo k, para 1 < k < n. Em outras palavras, em uma rvore binria completa os nodos externos aparecem em dois nveis adjacentes e os nodos no nvel mais baixo esto posicionados mais esquerda.

84

CAPITULO 3. ORDENAO

Figura 3.6: rvore binria completa

Uma rvore binria completa pode ser representada por um array, conforme ilustra a Figura 3.7. Esta representao extremamente compacta e, alm disso, permite caminhar pelos nodos da rvore facilmente: os filhos de um nodo i esto nas posies 2i e 2i + 1 (caso existam), e o pai de um nodo i est na posio i div 2.

Figura 3.7: rvore binria completa representada por um arranjo Um heap uma rvore binria completa na qual cada nodo satisfaz a condio do heap apresentada acima. No caso da representao do heap por um arranjo, a maior chave est sempre na posio 1 do vetor. Os algoritmos para implementar as operaes sobre o heap operam ao longo de um dos caminhos da rvore, a partir da raiz at o nvel inferior da rvore.

3.1. ORDENAO INTERNA

85

86

CAPTULO 3. ORDENAO

A partir do heap obtido pelo procedimento Constri, pega-se o item na posio 1 do vetor (raiz do heap) e troca-se com o item que est na posio n do vetor. A seguir, basta usar o procedimento Refaz para reconstituir o heap para os itens A[1], A[2], ..., A[n -1]. Repita estas duas operaes com os n 1 itens restantes, depois com os n 2 itens, at que reste apenas um item. Este mtodo exatamente o que o Heapsort faz, conforme ilustra a Figura 3. 9. 0 caminho seguido pelo procedimento Refaz para reconstituir a condio do heap est em negrito. Por exemplo, aps a troca dos itens S e D na segunda linha da Figura 3.9, o item D volta para a posio 5 aps passar pelas posies 1 e 2.

Figura 3.9: Exemplo de ordenao usando Heapsort

O Programa 3.9 mostra a implementao do algoritmo, para um conjunto de itens implementado como um tipo Vetor.

AnliseA primeira vista o algoritmo no parece eficiente, pois as chaves so movimentadas vrias vezes. Entretanto, o procedimento Refaz gasta cerca de log n operaes, no pior caso. Logo, Heapsort gasta um tempo de execuo proporcional a n log n no pior caso! Heapsort no recomendado para arquivos com poucos registros, por causa do tempo necessrio para construir o heap, bem como porque o anel interno do algoritmo bastante complexo, se comparado com o anel interno do Quicksort. De fato, Quicksort , em mdia, cerca de duas vezes mais rpido que o Heapsort. Entretanto, Heapsort melhor que o Shellsort para grandes arquivos. Um aspecto importante a favor do Heapsort que o seu comportamento O(n log n), qualquer que seja a entrada. Aplicaes que no podem tolerar eventualmente um caso desfavorvel devem usar o Heapsort. Um aspecto negativo sobre o Heapsort que o mtodo no estvel.

3.37. ORDENAO INTERNA

87

P r o g r a m a 3 . 9 : P r o c ed i m en to H ea p s o r t

3.1 . 6 C o m p a r a o Ent re o s Mt o d o sA ordenao interna utilizada quando todos os registros do arquivo ca-bem na memria principal. Neste captulo apresentamos cinco mtodos de ordenao interna atravs de comparao de chaves. Foram estudados dois mtodos simples (Seleo e Insero) que requerem 0(n2) comparaes e trs mtodos eficientes (Shellsort, Quicksort e Heapsort) que requerem 0(n log n) comparaes (apesar de no se conhecer analiticamente o comportamento do Shellsort, ele considerado um mtodo eficiente). As Tabelas 3.1, 3.2 e 3.3 apresentam quadros comparativos do tempo total real para ordenar arranjos com 500, 5.000, 10.000 e 30.000 registros na ordem aleatria, na ordem ascendente e na ordem descendente, respectivamente. Em cada tabela, o mtodo que levou menos tempo real para executar recebeu o valor 1 e os outros receberam valores relativos a ele. Assim, na Tabela 3.1, o Shellsort levou o dobro do tempo do Quicksort para ordenar 30.000 registros.

88500 Insero Seleo Shellsort Quicksort Heapsort 11.3 16.2 1.2 1 1.5 5000 87 124 1.6 1 1.6

CAPTULO 38. ORDENAO10000 161 228 1.7 1 1.6 30000 2 1 1.6

Tabela 3.1: Ordem aleatria dos registros

Insero Seleo Shellsort Quicksort Heapsort

500 1 128 3.9 4.1 12.2

1 5000 110000 1 1 1524 3066 6.8 7.3 6.3 6.8 20.8 22.4

30000 1 8.1 7.1 24.6

Tabela 3.2: Ordem ascendente dos registros500 40.3 29.3 1.5 1 2.5 5000 305 221 1.5 1 2.7 10000 575 417 1.6 1 2.7 30000 1.6 1 2.9

Insero Seleo Shellsort Quicksort Heapsort

Tabela 3.3: Ordem descendente dos registros

A seguir, apresentamos algumas observaes sobre cada um dos mtodos. 1. Shellsort, Quicksort e Heapsort tm a mesma ordem de grandeza. 2. O Quicksort o mais rpido para todos os tamanhos aleatrios experimentados. 3. A relao Heapsort/Quicksort se mantm constante para todos os tamanhos, sendo o Heapsort mais lento. 4. A relao Shellsort/Quicksort aumenta medida que o nmero de elementos aumenta; para arquivos pequenos (500 elementos) o Shellsort mais rpido que o Heapsort, porm quando o tamanho da entrada cresce, esta relao se inverte. 5. O Insero o mais rpido para qualquer tamanho se os elementos esto ordenados; este seu melhor caso, que 0(n). Ele o mais lento para qualquer tamanho se os elementos esto em ordem descendente; este o seu pior caso.

3.1. ORDENAO INTERNA

89

6. Entre os algoritmos de custo 0(n2) o Insero melhor para todos os tamanhos aleatrios experimentados. A Tabela 3.4 mostra a influncia da ordem inicial do arquivo sobre cada um dos trs mtodos mais eficientes. Ao observar a tabela podemos notar que:Shellsort Asc Des Ale 5000 1 1.5 2.9 10000 1 1.6 3.1 30000 1 1.5 3.7 5000 1 1.1 1.9 Quicksort 10000 1 1.1 2.0 30000 1 1.1 2.0 5000 1.1 1 1.1 Heapsort 10000 1.1 1 1 30000 1.1 1 1

T a b e l a 3.4: Influncia da ordem inicial

1. O Shellsort bastante sensvel ordenao ascendente ou descendente da entrada; para arquivos do mesmo tamanho executa mais rpido se o arquivo estiver ordenado do que se os elementos forem aleatrios. 2. O Quicksort sensvel ordenao ascendente ou descendente da entrada; para arquivos do mesmo tamanho executa mais rpido se o arquivo estiver ordenado do que se os elementos forem aleatrios. Ele o mais rpido para qualquer tamanho se os elementos esto em ordem ascendente. 3. O Heapsort praticamente no sensvel ordenao da entrada; para arquivos do mesmo tamanho executa 10% mais rpido se o arquivo estiver ordenado do que se os elementos forem aleatrios. O mtodo da Insero o mais interessante para arquivos com menos do que 20 elementos, podendo ser mais eficiente do que algoritmos que tenham comportamento assinttico mais eficiente. O mtodo estvel e seu comportamento melhor do que outro mtodo estvel muito citado na literatura, o Bubblesort ou mtodo da bolha. Alm disso, sua implemento to simples quanto 'as implementaes do Bubblesort e Seleo. Para arquivos j ordenados o mtodo 0(n): quando se deseja adicionar alguns elementos a um arquivo j ordenado e depois obter um outro arquivo ordenado o custo linear. O mtodo da Seleo somente vantajoso quanto ao nmero de movimentos de registros, que 0(n). Logo, ele deve ser usado para arquivos com registros muito grandes, desde que o tamanho do arquivo no seja maior do que 1.000 elementos. O Shellsort o mtodo a ser escolhido para a maioria das aplicaes por ser muito eficiente para arquivos de at 10.000 elementos. Mesmo para

90

CAPTULO 3. ORDENAO

arquivos grandes o mtodo cerca de apenas duas vezes mais lento do que o Quicksort. Sua implementao simples e fcil de colocar funcionando corretamente e geralmente resulta em um programa pequeno. Ele no possui um pior caso ruim e quando encontra um arquivo parcialmente ordenado trabalha menos. O Quicksort o algoritmo mais eficiente que existe para uma grande variedade de situaes. Entretanto, um mtodo bastante frgil no sentido de que qualquer erro de implementao pode ser difcil de ser detectado. O algoritmo recursivo, o que demanda uma pequena quantidade de memria adicional. Alm disso, seu desempenho da ordem de O ( n 2) operaes no pior caso. Uma vez que se consiga uma implementao robusta, o Quicksort deve ser o mtodo a ser utilizado. 0 principal cuidado a ser tomado com relao escolha do piv. A escolha do elemento do meio do arranjo melhora muito o desempenho quando o arquivo est total ou parcialmente ordenado, e o pior caso nestas condies tem uma probabilidade muito remota de ocorrer quando os elementos forem aleatrios. A melhor soluo para tornar o pior caso mais improvvel ainda escolher ao acaso uma pequena amostra do arranjo e usar a mediana da amostra como piv na partio. Geralmente se usa a mediana de uma amostra de trs elementos. Alm de tornar o pior caso muito mais improvvel esta soluo melhora o caso mdio ligeiramente. Outra importante melhoria para o desempenho do Quicksort evitar chamadas recursivas para pequenos subarquivos, atravs da chamada de um mtodo de ordenao simples, como o mtodo da Insero. Para tal, basta colocar um teste no incio do procedimento recursivo Ordena do Pro-grama 3.7 para verificar o tamanho do subarquivo a ser ordenado: para arquivos com menos do que 25 elementos o algoritmo da Insero deve ser chamado ( a implementao do algoritmo da Insero deve ser alterada para aceitar parmetros indicando os limites do subarquivo a ser ordenado). A melhoria no desempenho significativa, podendo chegar a 20% para a maio-ria das aplicaes (Sedgewick, 1988). O Heapsort um mtodo de ordenao elegante e eficiente. Apesar de possuir um anel interno relativamente complexo, que o torna cerca de duas vezes mais lento do que o Quicksort, ele no necessita nenhuma memria adicional. Alm disso, ele executa sempre em tempo proporcional a n log n, qualquer que seja a ordem inicial dos elementos do arquivo de entrada. Aplicaes que no podem tolerar eventuais variaes no tempo esperado de execuo devem usar o Heapsort. Finalmente, quando os registros do arquivo A[1], A[2], ..., A[n] so muito grandes desejvel que o mtodo de ordenao realize apenas n movimentos dos registros, atravs do uso de uma ordenao indireta. Isto pode ser realizado atravs da utilizao de um arranjo P[1], P[2], ..., P[n] de apontadores, um apontador para cada registro: os registros somente so acessados

3.41. ORDENAO EXTERNA

91

para fins de comparaes e toda movimentao realizada apenas sobre os apontadores. Ao final P[1] contm o ndice do menor elemento de A, P[2] contm o ndice do segundo menor elemento de A, e assim sucessivamente. Esta estratgia pode ser utilizada para qualquer dos mtodos de ordenao interna vistos anteriormente. Sedgewick (1988) mostra como implementar esta estratgia para o mtodo da Insero e para aplicaes de filas de prioridades usando Heaps.

3.2 Ordenao ExternaA ordenao externa envolve arquivos compostos por um nmero de registros que maior do que a memria interna do computador pode armazenar. Os mtodos de ordenao externa so muito diferentes dos mtodos de ordenao interna. Em ambos os casos o problema o mesmo: rearranjar os registros de um arquivo em ordem ascendente ou descendente. Entre-tanto, na ordenao externa as estruturas de dados tm que levar em conta o fato de que os dados esto armazenados em unidades de memria externa, relativamente muito mais lentas do que a memria principal. Nas memrias externas, tais como fitas, discos e tambores magnticos, os dados so armazenados como um arquivo seqencial, onde apenas um registro pode ser acessado em um dado momento. Esta uma restrio forte se comparada com as possibilidades de acesso da estrutura de dados do tipo vetor. Conseqentemente, os mtodos de ordenao interna apresentados na Seo 3.1 so inadequados para ordenao externa, e ento tnicas de ordenao completamente diferentes tm que ser usadas. Existem trs importantes fatores que fazem os algoritmos para ordenao externa diferentes dos algoritmos para ordenao interna, a saber: 1. O custo para acessar um item algumas ordens de grandeza maior do que os custos de processamento na memria interna. 0 custo principal na ordenao externa est relacionado com o custo de transferir dados entre a memria interna e a memria externa. 2. Existem restries severas de acesso aos dados. Por exemplo, os itens armazenados em fita magntica s podem ser acessados de forma seq uencial. Os itens armazenados em disco magntico podem ser acessados diretamente, mas a um custo maior do que o custo para acessar seqencialmente, o que contra-indica o uso do acesso direto. 3. O desenvolvimento de mtodos de ordenao externa muito dependente do estado atual da tecnologia. A grande variedade de tipos de unidades de memria externa pode tornar os mtodos de ordenao externa dependentes de vrios parmetros que afetam seus desempenhos.

92

CAPTULO 3. ORDENAO

Por esta razo, ape