Sie sind auf Seite 1von 22
Estruturas cc Dados e Algoritmos enC Distribuicso LIDEL SEDE: R.D. Estefania, 183, R/C Dto., 1049-057 LISBOA Internet: 21 354 14 18 - livraria@lidel pt / Revenda: 21 351 14.43 ~ revenda@lidel pt Formacao/Marketing: 21 351 14 48 —formacaoalidel.pt / marketing@tlidel pt Ensino Linguas/Exportacdo: 21 351 14 42 -depinternacionalalidel.pt Fax: 21 352 26 84 LIVRARIA: ‘Av. Praia da Vitéria, 14 ~ 1000-247 LISBOA Tel 21 354 14 18 ~ e-mail: liveariaalidel.pt Copyright © fevereiro 2014 (3* Edigdo Revista e Aumentada); agosto 2008 (1* Edico) FCA ~ Editora de Informatica, Lda. ISBN: 978.972-722.769-3 Capa: José Manuel Reis Iustragao da capa: Miguel Montenegro Impressio ¢ acabamento: Cafilesa ~ Solugses Graticas, Lda. ~ Venda de Pinheiro Depésito Legal N¢ Livro segundo 0 Novo Acordo Ortografico Todos 0s noss0s livros passam por um rigoroso controlo de qualidade, no entanto, aconselhamos a consulta periddica do nosso site (www fea.pt) para fazer o download de eventuais correcies. Os nomes comerciais referenciados neste livra ttm patente registada. MocesRegsss oot delomica cn =) roa, Dress fee FCA® Ginenenny ~) Reservados todos os direites, Esta publicago no pods ser reproduzida, nem transmitida, no todo ou em (0.| parte, por qualquer processo elewénice, mectnico, fotecspie, dgitalzagio, gravagio, sistema de ermazenamento @ cisponibilizago de informacao, sitio Web, Dogue cu cuts, sem prévie autorizac30 esctita da Echtora, exceto 0 peimitide pelo CDADC, em termes de copia privada pela AGECOP — Associaga0 para a Gestao da Copia Privade, através do pagamento das respebvas taxas, INDICE PREFAcIo XIII 1-RECURSIVIDADE 1 1.1 Introdugao.. 1.2 Caleulo do fatorial .. 1.3 Expansao em série de Taylor. ko 1.4 Numeros de Fibonacci 1.5 Caleulo dos coeficientes binom: 9 1.6 Calculo das permutagées. 12 1.7 Calculo do determinante de uma matriz wd 1.8 Torres de Handi 16 1.9 Eliminagio da recursividade .. 21 1.10 Recursividade com retrocesso .. 23 1.11 Questées sobre a eficiéncia da recur: 30 Exercicio 31 Leituras Recomendadas.. 34 2~-PROGRAMAGAO MODULAR 35 2.1 Introdugao... 35 2.2 Tipos de dados abstratos. 38 2.3 Médulos na linguagem C 40 2.4 Abstragdo de dados na linguagem C... 42 2.5 Gestdio da memoria dindmica ... 43 2.6 Controlo de erros 46 2.6.1 Programagio defensiva 46 2.6.1.1 Controlo centralizado de erro 7 2.6.1.2 Devolugao sistematica de um codigo de erro pelas operagies 0. .cscecere47 2.6.2 Programagao por contrato 48 2.6.2.1 Assergies........ sare — se sengid? “CA - Editera de Informatica ESTRUTURAS DE DADOS E ALGORITMOSEM C 2.6.3 Conelusbes so 2.7 Exemplo de um tipo de dados elemento matemstico. 2.8 Exemplo de um tipo de dados memoria 2.8.1 Implementagio concreta 2.8.2 Implementagio configurada 2.8.2.1 Elemento constituinte da memoria 66 Implementagao da meméria asta eciesenentnnieacststtensencscaiOD 2.8.2.3 Exemplo de utilizag&0 0 ses EE) 2.8.3 Implementagio genérica 75 Exercicios.. Leituras Recomendadas... 3.1 Introdugao 3.2 Listas simples 3.2.1 Algoritmos basicos 89 3.2.2 Simmilagtio das operagdes basicas da lista 95 3.2.3 Consideragées finais sobre listas simples. 96 3.3 Listas biligadas. 3.4 Listas skip Exercicio: Leituras Recomendada: 4.1 Introdugao 4.2 Arvore binaria de pesquisa. 4.2.1 Algoritmos basic: 4.2.2 Algoritmos de pesquisa e de selegao.. 121 4.2.3 Insergiio e remogio de elementos ...... : : 124 4.2.4 Travessias 130 4.2.5 Travessias ndo recursivas 132 4.2.6 Balanceamento...... 4.2.7 Visualizagao. 4.2.8 Simulagio da érvore binaria de pesquisa... ses sess 42, 4.2.9 Implementagao alternativa 4.3 Arvore de Adelson-Velskii Landis vi © FCA Editora de Informatica inpice 4.3.1 Insergdo de elementos a arvana isn ninvns enssaicen AS, 4.3.2 Remogiio de elementos 158 4.4 Arvore rubinegra 4.4.1 Insergao de elementos 4.4.2 Remogio de elementos 4.5 Arvore autoequilibrada. 4.5.1 Estrutura do né...... a 4.5.2 Abordagem recursiva (bottom-Up)) 0.0 csssseses ss sand TT 4.5.3 Abordagem repetitiva (top-down), 177 4.6 Amontoado binario. “ 4.6.1 Insergao e remogio de elementos........ a fo cst 186 4.6.2 Promogio e despromogio de elementos 189 4.6.3 Consideragées finais sobre amontoados «00. si seommeeal 92) 4.6.4 Simulagéio do amontoado Exercicio Leituras Recomendada: 5.1 Introdugao 5.2 Complexidade algoritmica 5.3 Pesquisa. 5.3.1 Pesquisa sequencial .. 5.3.2 Pesquisa binaria.. 5.3.3 Pesquisa temaria 5.3.4 Pesquisa por interpolagao 217 5.3.5 Pesquisa por dispersio. . 219 5.3.5.1 Deslocamento da posigao de colocagio.. 221 5.3.5.2 Encadeamento de elementos... ancenraenaceneranunesnnconsaite 226 5.3.5.3 ConsideragGes finais sobre a pesquisa por dispersto 229 5.3.6 Pesquisa por indexagio 231 5.4 Selegao. x 5.4.1 Selegao do maior valor..... 233 5.4.2 Selegao do menor valor .. . 234 5.4.3 Selegdo simultinea do maior e do menor VALOLO8 es vserenvnnnnnennnneneeen dBA 5.4.4 Selegao do primeiro valor que serve..... a seven essen 235 5.4.5 Selegio do melhor valor que serve 236 FCA - Editera de Informatica vu ESTRUTURAS DE DADOS E ALGORITMOSEM C 5.4.6 Selegao do pior valor que serve 5.4.7 Exemplificagao dos algoritmos de selegio 5.4.8 Selegdo do K-ésimo menor valor 238 5.5 Ordenagio .. 5.5.1 Ordenagio por selego 2 Ordenagio por troca... 5.5.3 Ordenagao por insergao 5.5.4 Comparagiio dos algoritmos de ordenagéo simples 5.6 Ordenagiio por fusiio 5.7 Algoritmos de ordenaco recursivos.. 5.7.1 Ordenagio por fusdo 5.7.2 Ordenago por separagtio 5.8 Algoritmo de ordenagio Heap.. 5.8.1 Construgao do amontoado 5.8.2 Implementagto do algoritmo .... 5.9 Generalizagao dos algoritmos de ordenagio 5.10 Av: co do desempenho dos algoritmos Exercicio: Leituras Recomendadas.... 6.1 Introdugao... 6.2 Caracterizagio da memoria de acesso aleatério .. 6.3 Caracterizagiio da memoria fila .. 6.4 Caracterizacao da memoria pilha .. 5 Caracterizagiio da meméria associativa . 6.6 Caracterizagio da memoria fila com prioridade 6.7 Tipos de implementagio.. 6.8 Implementacao da meméria de acesso aleato 6.9 Implementagao da memoria fila. 6.10 Implementagao da memoria pilha 6.11 Implementagao da memoria associativa 6.12 Implementagao da meméria fila com prioridade. 6.13 Consideracées finais sobre memorias vin © FCA Editora de Informatica inpice 7~FILASE PILHAS 307 7.1 Introdugio 7.2 Meméria fila. 7.2.1 Implementagao estitiea......c..00 7.2.2 Implementagao semiestatioa 0.000 a oss es 7.2.3 Implementagio dinamica 318 7.3 Memoria pilha.. 7.3.1 Implementagio estitica.... 7.3.2 Implementagao semiestatica 7.3.3 Implementagao dinamica... 7.4 Exemplos simples de aplicagio de filas e pilhas.. 7.5 Exemplos complexos de aplicagio de pilhas. 7.6 Implementacées genéricas. 7.7 Torres de Hanii... 7.8 Eliminagio da recursividade ..... 7.9 Memoria fila dupla Exercicio: Leituras Recomendada: 8.1 Introdugao 8.2 Configuracao da memoria ... 8.3 Meméria associativa estatica . 8.4 Meméria associativa semiestatica 8.5 Memoria associativa dindmica 8.5.1 Versao dinamica linear 8.5.2 Versio dindmica logaritmica. 8.5.3 Versio dindmica por dispersto 8.5.4 Versio dindmica hierarquica . 8.6 Exemplo de utilizagao... 8.7 Meméria associativa genérica. Exercicios.. 9.1 Introdugio..... FCA - Editora de Informatica 1 ESTRUTURAS DE DADOS E ALGORITMOSEM C 9.2 Fila com prioridade estatica ... 9.3 Fila com prioridade dinamica..... 9.4 Implementagiio com amontoado 9.5 Exemplo de utilizagao. 9.6 Fila com prioridade genérica.. Exercicios. . Leituras Recomendadas... 450 10-GRAFos 451 451 10.1 Introdugao... 10.2 Propriedades do grafo 10.3 Implementagao do grafo ... 10.4 Caracterizagao do grafo. 10.5 Digrafo/Grafo dinamico.. 10.6 Travessias 10.7 Ordenagio topolégica.. 10.8 Componentes fortemente conexas 10.9 Caminhos mais curtos 10.9.1 Vértices alcangaveis. coceeceeeeee eee sce wos coe 492 10.9.2 Caminho mais curto. ace wrote sic soseesee 49S 10.9.3 Todos os pares de caminhos mais curtos 507 10.9.4 Os K caminhos mais curtos ..... 10.10 Arvore abrangente de custo minimo. 10.10.1 Algoritmo de Prim eee so a - 10.10.2 Algoritmo de Kruskal «0.0.00. a a sv 516 10.11 Fecho transitivo. 10.12 Caminhos e circuitos hamiltonianos 10.13 Circuitos e caminhos eulerianos.... Exercicios...... Leituras Recomendadas.. 11.1 Unives... 11.2 Operadores bitwise. 11.3 Sequéncias de ponteiros para fungoes.... x © FCA Editora de Informatica inpice 11.4 Lista de pardmetros com comprimento variavel.. 11.5 Pré-processador da linguagem C ... 11.5.1 Macros de substituigio .... 11.5.2 Compilagdo condicional...... 11.5.3 Assergées 11.6 Compilagaio automatica 11.7 Tratamento de sinais... 11.8 Controlo de erros.. 11.9 Conjunto disjunto 11.10 Acesso indexado a ficheiros. 11.11 Pesquisa exaustiva .. 11.1.1 Quadrado magico 11.1.2 Subconjuntos de um conjunto 11.113 Carregamento otimizado da mochila a a evan STA 11.12 Algoritmos num éricos .. 11.12.1 Caleulo da poténcia..... . scent so 11.12.2 Avaliagiio do polinémio. outitineninianentisiuntatsnseeseen STD 11.12.3 Multiplicagao de polinémios 578 11.12.4 Multiplicagao de matrizes 580 Exereicio Leituras Recomendadas... GLOSSARIO DE TERMOS - PORTUGUES EUROPEU/PORTUGUES DO BRASIL 587 INDICE REMISSIVo 589 FCA - Editora de Informatica I. PREFACIO PROGRAMACAO EM LINGUAGEM C Hoje em dia, a Programagéo ¢ considerada uma ciéncia de base de qualquer curso da area cientifica das Ciéncias e das Engenharias, fazendo por isso parte do seu curriculo uma ou mais disciplinas de Ciéncia e Tecnologia da Programagao. No caso de cursos que exijam conceitos sdlidos de programagao e de desenvolvimento de software, é normal que o seu estudo seja feito em varias disciplinas. Desde disciplinas de introdugao 4 programagéo, dedicadas ao estudo de estruturas de dados basicas e de algoritmos simples, usando 0 paradigma procedimental, até disciplinas avangadas, dedicadas ao estudo de estruturas de dados avangadas ¢ de algoritmos mais complexos, eventualmente, fazendo um estudo de técnicas algoritmicas sofisticadas e de andlise da complexidade dos algoritmos, usando 0 paradigma modular, que permite combinar estruturas de dados e algoritmos na concegao de abstragées, indispensaveis para o desenvolvimento de aplicagées informaticas sofisticadas, que habitualmente designamos por tipos de dados abstratos A questiio que se coloca é se esas disciplinas devem ser lecionadas usando uma linguagem nao orientada a objetos, como a linguagem C, ou usando uma linguagem orientada a objetos, como a linguagem C++ ou a linguagem Java. A linguagem C tem a grande vantagem de ser uma linguagem de uso geral e adaptavel a qualquer area cientifica, que pemnite implementar os paradigmas procedimental e modular, que so mais intuitivos do que o paradigma orientado a objetos, na iniciagéo & aprendizagem da programagao. Como a Inguagem C combina as caracteristicas de uma linguagem de alto nivel com as caracteristicas do Assembly, cla pode ser usada como linguagem de suporte ao ensino de programagio em Assembly. Acresce ainda que a linguagem C foi desenvolvida para programagio de sistemas © esta intimamente ligada ao desenvolvimento do sistema operativo Unix, pelo que também é a linguagem adequada para o desenvolvimento de aplicagées de sistema Tendo isto em consideragao, em 2006 escrevi dois livros de programagiio usando a linguagem C: um primeiro livro, Introdhicdo & Programacéio usando C, para introduzir a linguagem C, as estruturas de dados estiticas e os ficheiros e para explorar o paradigma da programagio procedimental, e um segundo livro, Programagéio Avancada usando C, para estudar os aspetos mais avangados da linguagem C, as solugdes recursivas e as estruturas de dados dinamieas, e para explorar o paradigma da programagio modular FCA - Editera de Informatica ESTRUTURAS DE DADOS E ALGORITMOSEM C Entretanto, algumas disciplinas de programagdo, resultado da wiltima revisio curricular, tém vindo a dedicar-se ao estudo das estruturas de dados avangadas, das técnicas algoritmicas mais sofisticadas, da andlise da complexidade dos algoritmos e da construgio de abstragdes essenciais para o desenvolvimento de aplicagdes informéticas. A primeira edigéo do livro Estrutwas de Dados e Algoritmos em C exa, portanto, uma evolugio natural do livro Programagéio Avancada usando C, com um reforgo do estudo de estruturas de dados dindmicas avangadas, como so os casos das listas com atalhos ¢ da arvore de Adelson-Velskii Landis, bem como uma reorganizagao de alguns capitulos. Esta edigiio que tem nas suas méos é uma nova abordagem em termos de organizacdo global dos assuntos ¢ conta com um reforgo do estudo de algoritmos de drvores, nomeadamente com a introdugdo das arvores rubinegra e autoequilibrada, de algoritmos de grafos, de pesquisa exaustiva e numéricos. Este livro tem como objetivo fomecer uma competéneia sélida no desenvolvimento de programas de média e elevada complexidade, usando a linguagem de programagtio C e aplicando o paradigma da programagao modular. Assim, utiliza uma metodologia que da particular énfase decomposicao funcional das solugdes, através da implementagao de tipos de dados abstratos. Outro objetivo consiste na aprendizagem de técnicas mais avangadas de andlise da solugao de problemas, como as solugGes recursivas, sendo estudados os aspetos relacionados com a eficiéncia das solugdes. Também 6 objetivo introduzir as estruturas de dados ¢ os algoritmos que, tipicamente, so encontrados em programas de média e clevada complexidade, nomeadamente as estruturas de dados semiestaticas ¢ dindmicas. Especificamente, este livro pretende atingir os segnintes objetivos * © estudo de algoritmos recursivos, como alternativa 4 decomposigao hierirquica das solugdes, e a comparacdo com os algoritmos repetitivos equivalentes; = A gestio da memoria dinémica e o estudo de estruturas de dados dinamicas, nomeadamente das listas ligadas e das arvores, = Oestudo do paradigma da programagéo modular, que assenta na implementagéo de tipos de dados abstratos, comegando pelos tipos de dados que modelam elementos matemiticos, como, por exemplo, mimeros complexos, vetores, polinomios, matrizes e conjuntos, = © estudo da implementagao de tipos de dados abstratos, que armazenam eolegdes de dados, ou seja, 0 estudo dos diferentes tipos de memérias, nomeadamente da meméria de acesso aleatério, da meméria fila, da memoria pilha, da memoria associativa e da meméria fila com prioridade, e dos algoritmos associados para pesquisa, colocagiio e remogiio de informagiio, = Ocstudo da implementagio do tipo abstrato de dados grafo/digrafo xv © FCA Editora de Informatica PREFACIO| ORGANIZACAO DO LIVRO Em termos gerais, este livro esta organizado em seis partes, A primeiza parte é constituida pelos dois primeizos capitulos ¢ é dedicada a questées de engenharia de software, como a recursividade, como aspeto mais avaneado da programagio procedimental, e a introdugtio ao paradigma da programacao modular, que assenta na construgtio de tipos de dados abstratos. A segunda parte ¢ constitnida pelos dois capitulos seguintes e dedicada ao estudo das estruturas de dados dinamicas, nomeadamente das listas ligadas (linked lists) € das arvores (trees), A terceira parte é constituida pelo quinto capitulo e ¢ dedicada ao estudo dos algoritmos de pesquisa, de selegio e de ordenagio. A quarta parte é constituida pelos quatro capitulos seguintes ¢ é dedicada a caracterizagio dos diferentes tipos de memérias € ao estudo da memoria fila (Quewe), da memeéria pilha (Stack), da meméria associativa (Content Access Memory) e da meméria fila com prioridade (Priority Queue). A quinta parte € constituida pelo décimo capitulo e ¢ dedicada ao estudo do tipo de dados abstrato digrafo/erafo (Digraph/Grapli). Finalmente, a sexta parte € constituida pelo ultimo capitulo e é dedicada ao estudo de diversos topicos de programagio, mormente do tipo de dados abstrato conjunto disjunto (Disjoimt Sei), da técnica de pesquisa exaustiva e de alguns algoritmos numéricos. Vamos agora descrever com mais detalhe os capitulos constituintes do livro O Capitulo 1 apresenta um aspeto avangado da programaciio procedimental, que é a implementago de subprogramas recursivos. Através da apresentagio dos algoritmos recursivos classicos, stio estudados os varios aspetos associados a recursividade, nomeadamente a questio da sua eficiéncia, pelo que so abordados os algoritmos repetitivos equivalentes. Também ¢ apresentada a técnica de programagio dinamica (@namic programming) ¢ referida a utilizagio de pilhas, como alternativas a recursividade Finalmente, 6 explicada a técnica de exploragiio exaustiva de solugdes, como 6 0 caso da recursividade com retrocesso (backtracking), © Capitulo 2 apresenta 0 paradigma de programagio modular, que assenta na implementagao de médulos auténomos e coerentes, também designados por tipos de dados abstratos. A linguagem C néo tem suporte para os tipos de dados abstratos, mas pemnite a implementagao modular de aplicagées. Por isso, sfio descritas as caracteristicas dos ficheiros de interface e de implementagao de um modulo, bem como a sua compilagio separada. Sao enunciadas as caracteristicas dos dois tipos de dados abstratos fandamentais, especificadamente os que modelam elementos matematicos e os que armazenam colecSes de dados, também designados por membérias. So apresentadas as fimgGes da biblioteca de execugiio ANSI para a gestéo da meméria dinamica. Também ¢ explicado como se implementa a abstragéo de dados na linguagem C, recorrendo a ctiagiio de instincias do tipo de dados abstato na meméria dindmica e da sua manipulagio através de ponteizos. So também discutidas as metodologias de controlo de e1ros — programagiio defensiva e por contrato. Depois, é usado o mimero complexo como exemplo da implementagio de tipos de dados abstratos que modelam elementos mateméticos, servindo para apresentar a teoria sobre a implementagto de médulos, nomeadamente a implementagdo de construtores (inicializador e cépia) e do destrutor. FCA - Editera de Informatica xv ESTRUTURAS DE DADOS E ALGORITMOSEM C Finalmente, é usada uma meméria indexada simplificada para mostrar a criagiio destes tipos de dados, nas suas implementagées conereta, configurada e generalizada, Capitulo 3 apresenta a teoria das listas ligadas, sendo descritos os algoritmos de pesquisa, de insergiio e de remogao de elementos das listas: simplesmente ligadas (singly linked lists), duplamente ligadas (doubly linked lists) e com atalhos (skip lists). O Capitulo 4 apresenta a teoria das arvores. Comega por apresentar as propriedades matematicas das arvores binarias. Depois, sfo estndadas as arvores binarias de pesquisa (binary search trees), as axvores de Adelson-Velskii Landis (AVL irees), as arvores rubinegras (red-black trees) e as arvores autoequilibradas (splay trees), sendo deseritos os algoritmos de pesquisa, de insergiio e de remogio de elementos. Para a arvore binatia de pesquisa, apresentam-se também os algoritmos mais complexos, como as travessias em profimdidade recursivas, o balanceamento de uma divore e a sua visualizagio hicrarquizada. Séio também apresentadas as travessias em profundidade nfio recursivas, recomendo a uma pilha, e a travessia por niveis, recorrendo a uma fila. Sto ainda apresentadas a insergo e a pesquisa de elementos numa drvore binaria de pesquisa, em que © elemento processado 6 colocado na raiz da arvore. Para as restantes Arvores sto explicados apenas os seus algoritmos de insergo e de remogao de elementos, que stio mais complexos do que os da arvore binaria de pesquisa, devido a exigéncia de manutengao do equilibrio da arvore. Finalmente, é apresentado o caso particular das drvores completas, como sto os amontoados binatios (binary heaps) e os seus algoritmos O Capitulo 5 € dedicado ao estudo dos algoritmos de pesquisa, de selegdo e de ordenagtio Comega por referir a questo da complexidade algoritmica, a notagto O maitisculo € as principais ordens de complexidade algoritmica. A primeira parte do capitulo ¢ dedicada as principais téenicas de pesquisa, Sao apresentados os algoritmos de pesquisa sequencial, de pesquisa sequencial numa sequéncia ordenada, de pesquisa binaria (nas suas versGes repetitiva e recursiva), de pesquisa temaria e de pesquisa por interpolagio. Depois, siio abordados os aspetos fundamentais da pesquisa por dispersio, como as fiungées de dispersiio, os métodos para resolver o problema das colisées, nomeadamente a sondagem linear, a sondagem quadratica e 0 encadeamento de elementos, e os respetivos algoritmos de insergao e de pesquisa de elementos numa tabela de disperstio. Também é explicado 0 principio da pesquisa por indexagao. A segunda parte do capitulo é dedicada aos algoritmos de selegao, como a pesquisa de maximo, de minimo, do primeiro que serve, do melhor que serve, do pior que serve e do K-ésimo menor elemento. A terceira parte do capitulo é dedicada as principais téenicas de ordenagdo, como sejam a ordenagio por selegao, a ordenagio por troca, a ordenagéio por insergtio e a ordenagiio por fusiio, sendo apresentados os algoritmos mais representativos de cada técnica e as suas ofimizagdes, Sfio apresentados os algoritmos de ordenagao Sequencial, Selectio, Bubble, Shell (numa versio de trocas), Shaker, Inserguio, Shell (na sua versio original) e Fusao de Listas. De seguida, sAo apresentados os algoritmos de ordenago recursivos Merge (com e sem sequéncia auxiliar) © Quick. De seguida, é apresentado 0 algoritmo de ordenagao Heap, que usa a sequéncia como se fosse um amontoado binirio, tirando partido da eficiéncia dos seus algoritmos de © FCA Editora de Informatica PREFACIO| manipulagio. Finalmente, stio desenvolvidos dois aspetos importantes dos algoritmos de ordenagao, designadamente a sua generalizagao ¢ a avaliagao do seu desempenho O Capitulo 6 é dedicado a caracterizagao das memérias, nomeadamente da memoria de acesso aleatorio, da memoria fila, da memoria pilha, da memoria associativa e da memoria fila com prioridade. Sao apresentadas as suas caracteristicas ¢ as suas operagdes basicas. Também sao referidas as diferentes altemativas de utilizagéo da meméria do computador para implementar estruturas de dados, ou seja, as implementagées estaticas, semiestaticas e dinamicas, Finalmente, so expostas as estrutuas de dados que podem ser usadas para coneretizar os diferentes tipos de implementagao de cada memoria, Capitulo 7 apresenta as memérias fila (Queve) e pilha (Stack) e comega por descrever a sua ulilidade. Comega por apresentar as implementagoes estitica, semiestitica e dinimica, configuradas para armazenar elementos definidos extemamente através de um ficheizo de interface. As operagdes de colocagdio ¢ de remogio de clementos nas implementagdes estifica e dindmica sao explicadas graficamente, para melhor compreensio da utilizagtio das estrituras de dados de suporte das memorias. Sdo também apresentados varios exemplos simples e de média complexidade de utilizagdo destas memorias. Depois, apresenta uma implementagto genérica das memorias fila e pilha, baseada numa lista ligada. E mostrada ‘uma nova simulagio das Torres de Hanéi baseada em pilhas. De seguida, é apresentado um exemplo de transformagio de uma solugao recursiva, numa solugéo repetitiva que utiliza uma pilha, como elemento armazenador de informagao, Finalmente, so desctitas as caracteristicas e as operagdes basicas da memoria fila duplamente terminada (Deque) O Capitulo 8 apresenta a meméria associativa (Content Access Memory) e comega por descrever a sua utilidade. Aborda o elemento estruturado, constituinte da memoria associativa, que ¢ definido através de um tipo de dados da responsabilidade do utilizador Depois, apresenta as implementagées estatica, semiestatica e dinamicas (linear, logaritmica, por disperséio e hierarquica), configuradas para armazenar um elemento estruturado. As operagées de colocagio e de remogio de elementos nas implementagées estatica e dinamicas sao explicadas graficamente, para melhor compreensio da utilizagao das estruturas de dados de suporte da memoria associativa. E apresentado um exemplo de utilizagéo desta meméria para gerir uma base de dados. Finalmente, é mostrada uma implementagao genérica baseada mma lista biligada © Capitulo 9 ¢ dedicado ao estudo da fila com prioridade (Priority Queue) e comeca por descrever a sua utilidade. Sdo apresentadas as implementages estatica ordenada, estitica néo ordenada, dinamica ordenada e baseada num amontoado binario, configuradas através de um tipo de dados da responsabilidade do utilizador. As operagdes de colocaglio e de remogao de clementos so explicadas graficamente, para melhor compreensao da sua funcionalidade. Depois, apresenta um exemplo de utilizagao desta meméria para ordenar informacio. Finalmente, é mostrada uma implementagiio genérica baseada num amontoado dinatio. FCA - Editera de Informatica xvi ESTRUTURAS DE DADOS E ALGORITMOSEM C © Capitulo 10 € dedicado ao estudo do digrafo/grafo (Digraph/Grapli). Comega pela descrigdo das suas propriedades e pela definigdo de alguns conceitos associados a este tipo de dados abstrato. Sao apresentadas as implementagées: estatica, baseada numa matriz de adjacéncias; e dinamica, baseada numa lista de adjacéneias, sendo discutidas as suas vantagens e desvantagens. De seguida, 6 concretizada a implementagao dinamica das suas operagées basicas, que vai servir de base & exposigtio de um conjunto de algoritmos tipicos de digrafos e grafos. Primeizo, so estudados os algoritmos de travessia, em profundidade Depth First Search e em largura Breadth First Search, sendo de seguida apresentadas algumas das suas aplicagdes, como a ordenagao topoldgica e a detegdo de componentes fortemente conexas, usando o algoritmo de Kosaraju-Sharir. Depois, s40 estudados os algoritmos relacionados com a conectividade de um digrafo/grafo, comegando pela detegtio dos vértices alcangiveis, pelos algoritmos de Dijkstra, de Bellnan-Ford e variantes de travessias em largura e em profindidade, para determinar o caminho mais curto de um vértice para todos os seus vértices alcangaveis, ¢ pelo algoritmo de Floyd para determinar todos os pares de caminhos mais curtos. Sao também estudados os algoritmos de Prim e de Kruskal para determinar a arvore abrangente de custo minimo de um grafo. Tambem é apresentado 0 algoritmo de Warshall para fazer o fecho transitive de um digrafo Finalmente, séo apresentados os algoritmos para determinar caminhos e circuitos hamiltonianos e eulerianos em grafos. © Capitulo 11 apresenta diversos topicos de programacao. Mostra alguns aspetos avangados da linguagem C, como as unides e os operadores bitwise, que s4o normalmente usados em programago de sistemas operativos, as sequéncias de ponteiros para fungdes que permitem implementar aplicagdes baseadas em menus (menu driven applications) e a definigtio de subprogramas com lista varidvel de parimetros. Também s4o apresentados varios aspetos associados 4 compilagio, depuragdo © execugéo de programas, como as facilidades disponibilizadas pelo pré-processador, nomeadamente: as macros de substituigéio, a compilagéio condicional e as asserg6es, a compilagio automatica de aplicagdes usando makefiles ¢ o tratamento de sinais. Apresenta ainda um tipo de dados abstzato, para fazer o controlo centralizado de erros em aplicagSes distribuidas por diversos médulos, € 0 tipo de dados abstrato conjunto disjunto (Disjoint Se”) e os algoritmos Union! Find. Depois, apresenta 0 acesso indexado a ficheiros. De seguida, so apresentados trés exemplos de pesquisa exaustiva para determinar 0 quadrado magico (magic square problem), os subconjuntos de um conjunto (subsef sum probleni) © 0 carregamento otimizado da mochila (knapsack problem). Por iiltimo, so apresentados quatro algoritmos numézicos ¢ a sua implementagéo eficiente, como o caleulo da poténcia, a avaliagao do polinémio e a multiplicagio de polinémios e de matrizes. Esta obra disponibiliza ainda um Glossério com a correspondéncia dos principais termos técnicos para o portugués do Brasil. © FCA Editora de Informatica ESTRUTURAS DE DADOS E ALGORITMOSEM C Em alternativa, podemos implementar a operago de remogio repetitiva que se apresenta no Algoritmo 4.41. Se a arvore estiver vazia, a remogio termina, Caso contrario, a travessia nfo recursiva encontra o elemento se estiver na arvore. Se o elemento tem dois filhos, entéio é preciso fazer uma nova travessia nfo recursiva para encontrar 0 menor elemento da sua subarvore direita, copiar esse elemento e remové-lo da arvore. Nos restantes casos, so ajustadas as ligagdes do pai do elemento removido ou da raiz da arvore caso o elemento removido esteja na raiz. Mas, para fazer o percurso inverso do elemento removido até a raiz, para reequilibrar a arvore, é necessario usar uma pilha para armazenar os nos a0 longo da travessia da arvore, Quando a remogéo do elemento é efetuada com sucesso, a pilha ¢ esvaziada e todos os nés do caminho sao percorridos no sentido inverso e sto equilibrados, tal como no algoritmo de insercao. Finalmente, a pilha 6 destruida e a operagio de remogiio termina. Este algoritmo ¢ mais extenso e necesita de uma pilha, mas tem a vantagem de ser implementado num tinico subprograma, Como exercicio de treino, adapte o Programa 4.1 para simular a insergao e a remogao de elementos na Arvore AVL. Faga duas versées do programa: na primeira teste os algoritmos recursivos ¢ na segunda teste os algoritmos repetitivos. 4.4 ARVORE RUBINEGRA A arvore rubinegra (arvore ARN) (em inglés RBT — Red-Black Tree) é uma rvore de pesquisa equilibrada em altura, proposta por Leonidas Guibas e Robert Sedgewick em 1978, em que cada né € vermelho ou preto. Limitando a maneira de colorir os nés da arvore, podemos garantir que nenhum caminho tem mais do dobro dos nés do que qualquer outro caminho, pelo que a arvore fica aproximadamente equilibrada, sendo a altura de wma arvore com N elementos no maximo 2*log: (N+1) As regras de coloragao de um né da arvore rubinegra séo as seguintes * Cada né ou é vermelho ou é preto: + Araiz da arvore e os nés externos sao pretos, + Se um né é vermelho, os seus dois filhos sto pretos. O mesmo € dizer que um né vermelho tem um pai preto. Ou seja, munca existem dois nés vermelhos seguidos no mesmo caminho; * Todos os caminhos desde um né qualquer (incluindo a propria raiz) até um né externo tm o mesmo nitmero de nds pretos A Figura 4.30 apresenta duas drvores rubinegras, sendo que os nés vermelhos estio a branco. Cada caminho a partir da raiz tem dois nds pretos. O mimero de nés pretos da raiz até uma folha define a designada altura preta (black tree height) 160 © FCA Editora de Informatica Arvores: Para implementar esta operagdo de forma repetitiva, precisamos de uma pilha para manter os nds percorridos pela travessia, de maneira a poder fazer 0 percurso inverso até a raiz (usando a mesma estratégia do Algoritmo 4.41), fazendo as rotagdes para corrigir a coloragio dos nés e para inclinar a arvore para a esquerda. No entanto, a sua implementagfio nao ¢ trivial, antes pelo contrario, ¢ complexa e bastante extensa. Como a travessia para determinar o né a remover vai fazendo rotagées de nés pelo caminho, entio a ligagéo interna dos nds da arvore vai ficando alterada e, se nio houver a respetiva atualizagto, mesmo armazenando os nés percorridos numa pilha nao € depois possivel fazer a travessia ascendente para ajustar corretamente a arvore Como exercicio de treino, adapte o Programa 4.1 para simular as versées recursivas da insergo e da remogtio de elementos na arvore rubinegra. 4.5 ARVORE AUTOEQUILIBRADA A arvore binaria de pesquisa autoequilibrada (Splay Tree) foi proposta por Daniel Sleator e Robert Tarjan em 1985, com o objetivo de ter uma arvore binaria de pesquisa que agsegura que um qualquer mimero de operagdes sucessivas a partir de uma arvore vazia tem um custo linear logaritmico; 0 que nao significa que o custo por operagio seja logaritmico. Para uma longa sequéncia de operagdes, algumas das operagdes podem ter ‘um custo maior, enquanto outras podem ter um custo menor, pelo que cada operagio tem ‘uum custo amortizado logaritmico. E uma arvore binaria de pesquisa, em que as operagdes que visitam os nos reorganizam a arvore. Sempre que um elemento ¢ inserido, pesquisado ou removido da arvore, 0 elemento, ou 0 seu pai no caso da remogao, € colocado na raiz da arvore através da reorganizacao dos elementos da drvore — operagiio que em inglés se designa por splaving —, usando rotagdes a esquerda e 4 direita de elementos. Repare que para implementar esta operag4o no s4o necessirios atributos adicionais nos nés da arvore. A logica subjacente baseia-se no facto de ser previsivel que o elemento venha a ser de novo acedido no futuro proximo, dai ficar na raiz da drvore para o futuro acesso ser mais eficiente. Por outro lado, a consequente alteragiio da posigiio de outros elementos préximos do elemento acedido vai tomar mais eficiente o seu acesso posterior. A operagdo de reorganizagdo da arvore é uma sucessdo de rotagSes, que podem ser rotagées simples, que envolvem um elemento e o seu pai, ¢ rotagées duplas, que envolvem um elemento, o sen pai e 0 seu avé, para colocar o elemento acedido na raiz da arvore. A rotagao simples — designada por rotagiio zig — 6 aplicada quando o pai do elemento é a raiz da drvore, Nesse caso, uma simples rotagao a direita, se for um filho esquerdo, ou uma simples rotago 4 esquerda, se for um filho direito, coloca-o na raiz da arvore. A rotacao dupla pode ser de dois tipos. Se o elemento é um elemento externo da arvore, on seja, se € 0 filho esquerdo de um filho esquerdo ou um filho direito de um filho direito, entéo duas rotagdes simples seguidas do seu av6, respetivamente, a direita ou a FCA - Editera de Informatica 175 ESTRUTURAS DE DADOS E ALGORITMOSEM C esquerda, colocam-no na raiz, da arvore. Esta rotagao ¢ designada por rotagtio zigcig ea Figura 4.38 apresenta-a, no caso da rotagéio dupla para a direita Figura 4.38 - Rotago z/gzig a direita Se o elemento é um elemento interno da arvore, ou seja, se é 0 filho esquerdo de um filho direito ou um filho direito de um filho esquerdo, entao uma rotag4o simples do seu pai, seguida de uma rotagao simples do seu av no sentido contrario, coloca-o na raiz. da anvore. Esta rotagao é designada por rotagao zigzag e a Figura 4.39 apresenta-a, no caso da rotagao dupla para a esquerda-direita, Figura 4.39 - Rotagio zigzag a esquerda-direita 4.5.1 ESTRUTURA DONO O né da arvore autoequilibrada é idéntico ao né da arvore binaria de pesquisa — vamos designa-lo por SplayNode —, sendo o tipo né decomposto apresentado na Figura 4.40 Como exercicio de treino, implemente os algoritmos de criagao e de destruigiio de um nd decomposto. Implemente também as operagées de rotacao a direita e a esquerda, que so idénticas as que foram apresentadas para a arvore binaria de pesquisa com insergao na raiz da arvore (ver Algoritmo 4.28). Implemente ainda as operagées de impressto da arvore (SplayDisplay) e de destrnigao da drvore (SplayDestroy) 176 © FCA Editora de Informatica GRaFos Matriz de Adjacéncias Matriz de warehall. Figura 10.45 - Demonstragio da aplicacao do algoritmo de Warshall 10.12 CAMINHOS E CIRCUITOS HAMILTONIANOS ‘Um caminho hamiltoniano ¢ um caminho simples que percorre todos os vertices do grafo, © que implica que o grafo tem de ser conexo. Um grafo diz-se conexo se s6 posstir uma componente conexa, ou seja, se nao tiver vertices desconexos. Logo, para determinar se uum grafo é conexo, é preciso verificar o grau de todos os seus vertices e assegurar que nenhum vértice tem grau nulo, tal como se apresenta no Algoritmo 10.18. E preciso ter em consideragio que, mum grafo, cada aresta (v;,v;) € representada pelas arestas orientadas (v,, v,) ¢ (¥;, ¥), pelo que os semigraus incidente emergente de um vértice sio iguais, sendo o grau do vértice representado por qualquer um deles, O algoritmo testa todas as situagdes de ero, devolvendo o respetivo codigo de erro. Se o grafo nao for conexo, entio devolve o cédigo de erro NO_CONNECTED, sendio devolve ox. int GraphIsConnected (PtDigraph pgraph) { PtBiNode V; 4£ (pgraph if (pgraph-=NVertexes if (pgraph->NEdges NULL || pgraph->Type) return NO_DIGRAPH; 0) return DIGRAPH_EMBTY; 0) return NO_EDGE; for (V = pgraph->Head; V != NULL; V = V->PtNext) 1f (((BtVertex) V->PtElem)->InDeg == 0) return NO_CONNECTED; return OK; Algoritmo 10.18 - Verificacao de grafo conexo Uma forma de detetar um caminho hamiltoniano entre dois vertices consiste em fazer ‘uma travessia em profimndidade a partir do primeiro vértice (vértice de partida) até atingir © segundo vertice (vértice de chegada), atravessando exatamente V-I arestas. A detegio de um caminho hamiltoniano que se apresenta no Algoritmo 10.19 ¢, portanto, uma adaptagio do algoritmo recursivo de travessia em profundidade, que tem dois vertices como parametros de entrada e que verifica se existe um caminho simples entre eles. (FCA Edtora de Informatica S2i GRaFos Como exercicio de treino, implemente um programa que cria um grafo e que apresenta no monitor 0 grafo, todos os caminhos hamiltonianos entre pares de vertices distintos e os circuitos hamiltonianos existentes para todos os seus vertices. 10.13 CIRCUITOS E CAMINHOS EULERIANOS Um grafo tem um circuito euleriano se, e 86 se, é conexo e se todos os seus vertices tem um grau par. Nesse caso, 0 grafo designa-se por grafo euleriano. O Algoritmo 10.21 utiliza esta propriedade para determinar se o grafo tem ou no um circuito euleriano. O algoritmo testa todas as situagdes de erro, devolvendo o respetivo cédigo de erro. Para no ter de definir um novo cédigo de erro, vamos usar 0 cédigo No_paTH para indicar que num grafo conexo nao existe um circuito euleriano. int GraphHasEulerTour (PtDigraph pgraph) { PtBiNode V; unsigned int Error, Degree; if ((Error = GraphIsConnected (pgraph)) != OK) return Error; for (V = pgraph->Head; V != NULL; V = V->PtNext) { Degree = [(PtVertex) V->PtBlem) ->InDeg; if (Degree == 0 || Degree $ 2 != 0 ) return NO_PATH; } return 0x; } Algoritmo 10.21 - Verificagao de existéncia de circuito euleriano num grafo Num grafo euleriano, como todos os vértices tém um mimero par de arestas, um caminho que comega num vértice consegue sempre terminar nesse vértice. No entanto, o caminho pode niio percorrer todas as arestas do grafo. Assim, para obter um eircuito ¢ preciso fazer varios ciclos (cireuitos parcelares) compostos por arestas distintas, de modo a esgotar todas as arestas do grafo. Para percomer as arestas do grafo apenas uma vez, podemos retira-las do grafo durante os sncessivos percursos. Assim, este modo de atuagio corompe o grafo, pelo que deve ser previamente copiado. Portanto, podemos construir um circuito euleriano com um conjunto de circuitos parcelares disjuntos, que depois stio interligados nos vértices de conexao. Ou seja, os circuitos parcelares s4o imbricados de maneira a criarem 0 circuito euleriano final. Este é 0 principio do algoritmo de Carl Hietholzer (1873) para determinar um cireuito euleriano Por exemplo, no grafo da Figura 10.47 temos os circuitos parcelares disjuntos (1, 2, 3, 1), (3. 4,2, 5,7, 4,6, 3) e (6, 7,8, 6), com o primeiro e o segundo ligados no vértice 3 € 0 segundo e 0 terceiro ligados no vértice 6. Para obtermos o circuito euleriano temos de substituir 0 vértice 3 do primeiro circuito pelo segundo cireuito e substituir o vértice 6 do segundo cireito pelo terceiro circuito, obtendo assim 0 cireuito final (1,2, 3, 4,2, 5,7, 4, ©, 7,8, 6), 3), D. (FCA Edtora de Informatica 525 Q esi romero Estruturas .. Dados rR Resonate oC Raley TO cn eS es Cue (CSc) era sister Rect iuenod ieital ese sec ce de dados avancadas e algoritmos complexos, usando a lin- RC Sc Ree ect kc) PR ete Chute ae Cm ear er Cnt ain Ce Moca cee na a através da implementacao de tipos de dados abstratos. Inclui ete Ne cream te eee Ce ecu omc vista a facilitar a aprendizagem dos alunos. CCRC eon Re MCE UI Ne ico leu sieue es * Estudo do paradigma da programagao modular na lin- guagem C, apresentando os aspetos fundamentals para TRC ee eee cee rect tac dologia de programacao defensiva; See Otel eco eee Sree ot tere Tee eek en ae + Estudo da implementaco dos diferentes tipos de memérias; SFO RR OR oe ac Me Oc Rea Pee ae ereM ste C coe Este livro é dirigido aos estudantes de disciplinas de progra- Pre OMe res Mn Lee TM Od ee oe eees tel eae te Mt met selneacM nets lM oc Ele eet re ee eee te et cre) Cnet OSes ener Reena} EM csc ts rex one Rests se ne Ree te) ce Rear Cree to is ui Hi e Algoritmos - C Nesta nova edicao foram acrescentadas seccdes sobre Arvore Rubinegra, Arvore Autoequilibrada, Caminhos € Circuitos Hamiltonianos, Circuitos e Caminhos Eulerianos. Principais temas abordados no livro: + Recursividade; + Programacao Modular; + Listas; * Arvores; * Pesquisa, Selecio e Ordenacao; + Memérias; * Filas e Pilhas; + Memérias Associativas; * Filas com Prioridade; * Grafos; * Outros Tépicos de Programagao. Implementacao de tipos de dados abstratos na linguagem C; Algoritmos e estruturas de dados fundamentais para escrever programas de média e elevada complexidade. Propramas aoresentados na obra cispo em www.fea.pl,2ié 0 fo se esgoar pbicada nova eo atta ‘am alerapdes, una pagina pessal do autor, em hitp://sweet.uapt/-1706/ensino/vres/htm.

Das könnte Ihnen auch gefallen