Sunteți pe pagina 1din 24

MATEUS CONRAD BARCELLOS DA COSTA

Algoritmos e Estruturas de
Dados
















M. B. Costa Algoritmos e Estruturas de Dados
2


[ Serra, ES ]
[ 2008 ]
M. B. Costa Algoritmos e Estruturas de Dados
3






Referncias utilizadas na elaborao deste material

1. LISKOV B. Data Abstraction and Hiararchy. In OOPSLA87:
Conference on Object Oriented Programming Systems Languages and
Applications. Addendum to the proceedings on Object-oriented
programming systems, languages and applications, 1987.
2. TENENBAUM A. M. Data Structs using C. Prentice Hall Int.
Editions, 1990.
3. ZIVIANI N. Projeto de Algoritmos. Segunda Edio. Pioneira, 2003.
M. B. Costa Algoritmos e Estruturas de Dados
4



Meu nome Mateus Barcellos Costa, sou professor e pesquisador do Ifes
desde 2005. Atuo na rea de Engenharia de Software e em disciplinas de
Programao. Se voc quiser mais informaes sobre mim e sobre os
trabalhos que desenvolvo, pode visitar minha pgina pessoal em
http://www.sr.cefetes.br/~mcosta.
Produzi o material que ora lhe apresento como instrumento bsico para o
estudo da disciplina de Tcnicas de Programao Avanada. Nesta disciplina
iremos aprofundar nossos conhecimentos em Programao de Computadores
usando uma linguagem imperativa. Exemplos destas linguagens so C e
Pascal. Iremos adotar a linguagem C, em nossos exemplos e
implementaes. No entanto, preciso que voc saiba que os conceitos
estudados aqui vo alm da linguagem e podem ser aplicados em diversos
cenrios, na programao e na Engenharia de Software como um todo.



M. B. Costa Algoritmos e Estruturas de Dados
5

Sumrio
1 Abstrao de dados ...................................................................................... 7
1.1 Introduo ............................................................................................ 7
1.2 Conceitos de abstrao de dados .......................................................... 9
1.2.1 Abstrao em Computao ........................................................... 9
1.2.2 Abstrao de Procedimentos ...................................................... 11
1.2.3 Tipos Abstratos de Dados .......................................................... 13
1.2.4 Implementao de Tipos Abstratos de Dados ............................ 19
1.2.5 Avaliao de Implementaes de Tipos Abstratos de Dados ..... 20
2 Tipos Abstratos de Dados Fundamentais ................................................... 25
2.1 Pilhas .................................................................................................. 25
2.1.1 Especificao do TAD Pilha ...................................................... 26
2.1.2 Implementao de Pilhas em Arranjos ....................................... 28
2.2 Filas .................................................................................................... 31
2.2.1 Especificao do TAD FILA ...................................................... 32
2.2.2 Implementao de Filas em arranjos com deslocamento ........... 35
2.2.3 Implementao de Filas com Arranjos circulares ...................... 37
2.3 Implementao de TADS com alocao dinmica de memria ......... 40
2.3.1 Reviso de Alocao Dinmica de Memria ............................. 40
2.3.2 Implementao do TAD Pilha .................................................... 47
2.3.3 Implementao do TAD Fila ...................................................... 50
3 Listas e rvores .......................................................................................... 55
3.1 Listas Circulares ................................................................................. 55
3.2 Lista Circular Duplamente encadeada ................................................ 64
3.3 rvores Binrias ................................................................................. 69
3.3.1 rvore Binria de Pesquisa ........................................................ 70
3.3.2 O TAD rvore Binria de Pesquisa ........................................... 71
3.3.3 Implementao do TAD rvore Binria de Pesquisa ................. 72
4 Pesquisa em Memria Primria .................................................................. 83
4.1 Pesquisa Sequencial ........................................................................... 85
4.1.1 Implementao da Pesquisa Seqencial ..................................... 86
4.1.2 Tempo de execuo de algoritmos ............................................. 87
4.2 Pesquisa Binria ................................................................................. 89
4.3 Tabelas Hash ...................................................................................... 92
4.3.1 Operaes de Insero e Pesquisa em Tabelas Hash ................. 94
M. B. Costa Algoritmos e Estruturas de Dados
6

4.3.2 Tratamento de Colises .............................................................. 96
4.3.3 Tratamento de Coliso usando endereamento Aberto .............. 98
5 Ordenao em Memria Primria ............................................................ 100
5.1 Conceitos Bsicos de ordenao ...................................................... 100
5.1.1 Operaes Tpicas de processos de Ordenao ........................ 100
5.2 Mtodos de Ordenao ..................................................................... 101
5.2.1 Ordenao por Seleo ............................................................. 101
5.2.2 Mtodo da Insero .................................................................. 103
5.2.3 Mtodo da Bolha ...................................................................... 104
5.2.4 Desempenho dos mtodos de Seleo, Insero e Bolha ........ 105
5.2.5 Mtodo de Shell ....................................................................... 106
5.2.6 O Mtodo Quicksort ................................................................. 109


M. B. Costa Algoritmos e Estruturas de Dados
7




1 ABSTRAO DE DADOS


Ol! Neste Captulo iremos discutir e aprender sobre Abstrao de Dados.
Abstrao de Dados uma tcnica de programao que visa simplificar o
desenvolvimento de programas. Sua aplicao pode se dar no
desenvolvimento de programas menores. Mas podemos afirmar que seria
impossvel o desenvolvimento de sistemas que temos hoje, com milhes de
linhas de cdigo, sem o uso de abstrao de dados.

1.1 INTRODUO
Um programa de computador desenvolvido para atender alguma finalidade
prtica , normalmente, um artefato complexo. Por esse motivo, a atividade de
desenvolvimento desses artefatos, a programao de computadores, est entre as
atividades mais complexas desempenhadas pelo homem. Se voc cursou
disciplinas introdutrias de programao, pode estar se questionando: Ora,
desenvolver um programa no to complexo assim! Basta compreender o problema,
suas entradas e suas sadas e construir a soluo usando uma linguagem de
programao. Simples no? No! A histria da programao tem dado provas
que programar no to simples assim.


Figura 1.1: O Gap Semntico.
Programar uma atividade complexa por diversos aspectos, tanto de cunho
terico quanto prtico. Dentre estes aspectos destacamos os seguintes:
1. Programar um computador significa desenvolver programas de
computadores (formais e precisos) para atender a finalidades prticas
definidas em termos de conceitos do mundo real (informais e
imprecisos). Existe um abismo entre o mundo dos problemas reais e o
mundo das solues. Esse abismo chamado na computao de gap
semntico. Transpor o abismo um dos desafios centrais da
programao de computadores e da Engenharia de Software como um
M. B. Costa Algoritmos e Estruturas de Dados
8

todo. A Figura 1.1 uma alegoria que busca mostrar a funo do
desenvolvedor de software: Transpor o abismo entre o mundo informal
(dos problemas) e o mundo formal (das solues computacionais).
Nessa transposio existem muitos desafios e perigos que podem
dificultar a trajetria do desenvolvedor.
2. Muitas vezes, em disciplinas iniciais de programao, deparamo-nos
com o desenvolvimento de programas mais simples, de cunho didtico.
Por exemplo, programas para calcular mdias ou somatrios. Em outros
momentos fazemos programas para aprender a usar um certo
mecanismo, por exemplo, apontadores. Aqui, estamos nos referindo a
programas de computadores para ajudar pessoas a resolverem problemas
do mundo real, problemas grandes e complexos! Exemplos desses
problemas incluem:
a. Gerenciar as operaes financeiras de uma empresa;
b. Controlar uma aeronave;
c. Controlar os trens de uma malha ferroviria;
d. Produzir edies dirias de um jornal;
e. Gerenciar o processo de produo de um filme.
3. Problemas como esses no so simples de se resolver.
Conseqentemente, programas voltados para essas finalidades so
complexos, levam muito tempo para ficar prontos, tm de ser
desenvolvidos por uma equipe de pessoas, utilizando diversas
tecnologias e seguindo um processo de desenvolvimento sistemtico.
4. Para atender s funcionalidades esperadas, um programa deve
apresentar um conjunto de caractersticas que juntas vo tornar o
programa efetivamente til e determinaro a qualidade do mesmo.
Essas caractersticas so as seguintes:
a. Um programa deve estar correto, livre de erros;
b. Um programa deve ser robusto. Um programa robusto ou
sistema robusto aquele que consegue funcionar, mesmo que
precariamente, diante de uma adversidade. Por exemplo,
suponha que um programa precise dos dados x, y e z para
realizar uma tarefa. Se este for robusto, na falta de um dos
dados, o programa pode tentar realizar o processamento possvel
com a ausncia dado;
c. Um programa deve ser eficiente. A eficincia de um programa
est relacionada ao seu tempo de execuo (eficincia na
execuo) ou ao espao em memria (eficincia na ocupao)
de que necessita para executar (rea de dados). Para um
problema h infinitas solues (programas). Quanto menores
esses valores mais eficiente o programa. Em computao pode-
se verificar se uma soluo tima (mais eficiente possvel)
para um problema;
d. Um programa deve ser compatvel com outros programas;
e. Um programa deve ser fcil de usar;
M. B. Costa Algoritmos e Estruturas de Dados
9

f. Um programa deve ser portvel, podendo funcionar em
diferentes plataformas ou sistemas operacionais;
g. Um programa deve ser ntegro, ou seja, deve evitar que os dados
sejam corrompidos ou violados;
h. O processamento realizado pelo programa deve ser verificvel;
i. O programa ou partes dele devem poder ser utilizados em outros
cenrios diferentes daquele para o qual o programa foi
originalmente desenvolvido.
5. Por ltimo, devemos considerar a atividade de programao como
atividade econmica. Assim como outras atividades econmicas, o
desenvolvimento de software regido por leis de mercado que impem
severas exigncias aos desenvolvedores. De acordo com essas leis, no
basta apenas desenvolver um programa que atenda finalidade
esperada. Esses programas devem ser desenvolvidos dentro dos prazos
e custos estabelecidos. Alm disso, o programa precisa ter outras
caractersticas importantes que permitam a sua evoluo. Essas
caractersticas so chamadas de fatores internos. So eles:
a. Facilidade de manuteno;
b. Facilidade de evoluo;
c. Fcililade de entendimento;
d. Modularidade.
Pelos motivos discutidos acima, o desenvolvimento de programas requer a
aplicao de princpios, mtodos e tcnicas que diminuam a complexidade desse
desenvolvimento. A Abstrao de Dados envolve uma srie de conceitos e
princpios para esse fim. A seguir discutiremos esses conceitos.

Atividade 1
Nesta introduo foram levantados cinco aspectos que tornam o
desenvolvimento de software uma tarefa difcil. Para atacar esses
aspectos e tornar o desenvolvimento de software mais simples so
consideradas trs dimenses: Processo de desenvolvimento, Pessoas
(partes interessadas: clientes, desenvolvedores) e Tecnologias de
desenvolvimento. Releia os cinco motivos e tente escrever um texto
resumido, estabelecendo uma relao entre esses 5 motivos e essas
trs dimenses.
1.2 CONCEITOS DE ABSTRAO DE DADOS
1.2.1 Abstrao em Computao
A abstrao um dos conceitos mais importantes da computao. Sem o uso
deste conceito podemos afirmar que a evoluo apresentada pela computao
teria sido mais lenta.
Segundo o dicionrio Michaelis, temos a seguinte definio para a palavra
Abstrao:
M. B. Costa Algoritmos e Estruturas de Dados
10

1. O ato ou efeito de abstrair. Considerao das qualidades independentemente
dos objetos a que pertencem. Abstrair: Considerar um dos caracteres de um
objeto separadamente;2. Excluir, prescindir de.
A finalidade principal de uso de abstrao em qualquer rea do conhecimento
colocarmos foco em um subconjunto dos aspectos de um sistema ou processo
complexo. Considere, por exemplo, o processo de pintar um quadro. A Figura
1.2 mostra, esquerda um esquema inicial mostrando as linhas principais do
quadro que se encontra do lado direito (A Virgem, o Menino e SantAna,
Leonardo Da Vinci).









Figura 1.2: Abstrao na Pintura.
Observe que, no desenho, as propores, os detalhes das posturas e feies so
j determinados. Esse processo ajuda o pintor pois, no momento da idealizao
do quadro, ele no precisa se preocupar com outros aspectos complexos, como
cores, nuances de sombras e reflexos, para definir a estrutura e a sua aparncia
geral. Podemos dizer ento que o desenho esquerda uma abstrao do
quadro.
Em computao, abstrao tambm possui finalidades semelhantes. Em
programao, especificamente, esse conceito est presente quase o tempo todo,
seja nas construes existentes nas linguagens, seja nos mtodos de
programao empregados.
Uma das principais abstraes das linguagens de programao o conceito de
varivel. Uma varivel um conceito abstrato que esconde diversos aspectos
tcnicos que no interessam ao programador. Quando declaramos uma varivel
em um programa, essa declarao implica em coisas que no iro interferir no
seu desenvolvimento. Por exemplo, por trs de uma varivel do tipo inteiro em
C, (ex. int x;), esto escondidas as caractersticas fsicas do armazenamento da
varivel em memria, a saber:
- A forma de representao de nmeros inteiros usando base 2 (por
exemplo, complemento de 2);
- O padro usado pelo hardware (ex. little endian, big endian);
- O nmero de bytes que uma varivel do tipo inteiro ocupa;
- O endereo da varivel na memria principal;
- O conjunto de bits responsvel por armazenar o sinal do nmero inteiro.

M. B. Costa Algoritmos e Estruturas de Dados
11

Para o programador em C, geralmente, nenhuma dessas informaes
importante. O que o programador deseja utilizar a varivel realizando as
operaes permitidas aos nmeros inteiros (operaes aritmticas e
comparaes), atribuir, recuperar e modificar o valor contido na varivel.
Assim podemos dizer que uma varivel permite ao programador abstrair-se
de detalhes que no interessam e no iro influenciar no comportamento do
programa.

Atividade 2
Os itens 1,2 e 3 so todos abstraes. Para cada um deles
descreva os aspectos que esto sendo escondidos e os aspectos
que realmente importam ao programador:
1. O comando
if(){
..
}
else{
..
}
2. um arquivo
3. a funo scanf



1.2.2 Abstrao de Procedimentos
Podemos afirmar que a grande maioria dos elementos de linguagem utilizados
em uma linguagem de programao de alto nvel so abstraes. Essas
abstraes facilitaram o desenvolvimento de programas mais complexos e
sofisticados, evitando que programadores precisassem manipular bits e
endereos de memria e interagir diretamente com o sistema operacional.
Uma outra abstrao de programao importante a Abstrao de
Procedimento.
Abstrao de Procedimento
A abstrao de procedimento permite que o programador crie, ele mesmo, sua
forma de abstrair, utilizando os comandos disponveis na linguagem. A
possibilidade de criar procedimentos permite ao programador criar
funcionalidades mais abstratas que escondem a seqncia de operaes
necessria para a realizao de uma tarefa complexa.

Por exemplo, sabemos que na linguagem C no existe um comando que seja
capaz de ordenar um vetor de inteiros em ordem crescente. Seria muito bom que
pudssemos contar com esse comando, certo? Mas, como no temos esse
comando, iremos criar uma funo (abstrao de procedimento) que realize essa
tarefa para ns. A funo ordena na Figura 1.3 essa abstrao.
M. B. Costa Algoritmos e Estruturas de Dados
12










Figura 1.3: Funo ordena: Cria uma abstrao do procedimento de ordenao.

Aps a implementao da funo ordena, quando o programador precisar
ordenar um vetor, basta que ele invoque a funo, passando os parmetros
necessrios. Ou seja, ao usar o procedimento, o programador ir se preocupar
apenas com o que a funo faz e no mais com os detalhes de sua
implementao.
Uma abstrao de procedimento deve realizar uma tarefa (por exemplo, ordenar
um vetor de inteiros) que deve ser independente da forma como este vai ser
implementado. O programador deve antes de tudo ver o procedimento como
uma caixa preta, cuja especificao deve conter trs elementos bsicos (Figura
1.4):
Entrada: O conjunto de dados de entrada necessrio;
Sada: O conjunto de dados produzido pelo procedimento;
Funo: A descrio do que o procedimento faz.



Figura 1.4: Os elementos considerados na definio de um procedimento.

Na especificao do procedimento, o programador no deve estar preocupado
com a implementao, mas sim com o comportamento (funo) do mesmo.
Qualquer implementao que realize a funo especificada ir servir como
soluo . Para o caso da ordenao, veremos adiante neste curso que existem
diferentes mtodos de ordenar um vetor. O mtodo utilizado na funo ordena
se chama ordenao por insero. A implementao interna poderia ser
substituda por qualquer outro mtodo de ordenao. A prpria linguagem C
oferece em sua biblioteca padro stdlib, uma funo chamada qsort, que
pode ser usada para ordenar vetores. Essa funo utiliza um outro mtodo de
ordenao muito conhecido e tambm muito rpido, chamado de Quick Sort.

void ordena(int a[], int tamanho) {
int i, j, valor;

for(i = 1; i < tamanho; ++i) {
value = a[i];
for (j = i - 1; j >= 0 && a[j] > value; --j){
a[j + 1] = a[j];
}
a[j+1] = valor;
}
}


ENTRADA SADA
FUNO
M. B. Costa Algoritmos e Estruturas de Dados
13

Atividade 3:
1. Suponha que voc tenha disponveis as seguintes funes
em C:
Int CalculaMedia(int *notas);
Void DeterminaMaiorEMenorNotas(int *v, int
* maior, int *menor);
Void leNotas(int *notas);
Void MostraResultados(int media,int
maiorNota, int menorNota);
Utilizando essas funes, desenvolva um programa em C
que leia as notas de 5 turmas e para cada uma delas,
imprima a mdia, a maior e a menor nota.
1.2.3 Tipos Abstratos de Dados
A abstrao de dados visa aos mesmos objetivos que a abstrao de
procedimentos, mas com relao s estruturas de dados utilizadas nos
programas. A abstrao de dados visa criar novos tipos de dados definidos em
temos de seu comportamento. Esses novos tipos so chamados de Tipos
Abstratos de Dados - TAD.
muito importante que voc perceba que um tipo abstrato de dados no se
resume a uma nova estrutura de dados. Vamos ento discutir um pouco sobre
essa diferena.
Primeiramente, uma estrutura de dados pode ser definida simplesmente como
uma varivel capaz de armazenar mais de um valor simultaneamente. Assim, um
vetor, uma matriz ou um registro (struct em C) so exemplos de estruturas de
dados. A combinao desses elementos em estruturas mais complexas d origem
a outras estruturas de dados. A Figura 1.5 apresenta as declaraes de struct
ponto e struct reta, como exemplos de tipos de estruturas de dado.





Figura 1.5: Estruturas de Dados ponto e reta.

Ao definir a struct ponto, passamos a contar com mais uma alternativa
para definio de tipos de variveis e, conseqentemente, para a composio de
novos tipos de estruturas. Assim a struct reta foi definida como uma
composio de duas variveis do tipo struct ponto. Essas estruturas
podem ser usadas para declarar tanto variveis como argumentos de funes.
Em C temos ainda a clusula typedef, que permite definir o nome do novo
tipo. Nesse caso, no precisamos usar a palavra reservada struct na
declarao de variveis do tipo definido. Na Figura 1.6 temos o uso de
struct ponto{
float x, y;
};
struct reta {
struct ponto a,b;
};
M. B. Costa Algoritmos e Estruturas de Dados
14

typedef. Veja que na definio do tipo Reta, o nome Ponto usado sem a
palavra reservada struct.




Figura 1.6: Definio dos tipo Reta e Ponto.


Estrutura de Dados versus Tipo Abstrato de Dados
A definio de uma estrutura de dados se preocupa em demonstrar como o
objeto representado na memria de um computador (representao). Nessa
definio so considerados aspectos do tipo: quais as informaes que sero
armazenadas ali e qual a quantidade destas informaes. A definio de um
Tipo Abstrato de Dados segue uma abordagem diferente. Essa definio
feita em termos das operaes que podem ser realizadas sobre o tipo.
A definio de um Tipo Abstrato de Dado (TAD) chamada de especificao
e consiste, basicamente, em definir as operaes relacionadas ao tipo.
Dizemos que essas operaes definem o comportamento do TAD.

Vamos aplicar o conceito de TAD considerando os objetos Reta e Ponto. Um
passo importante na definio do TAD, que j ajuda na programao de uma
maneira geral, que no conseguimos defini-lo sem conhecermos a sua
finalidade e o contexto no qual ser usado. Em nosso exemplo precisamos
saber para qu? ns queremos um ponto e uma reta. Geralmente essa
informao conseguida a partir do enunciado do problema. Assim, vamos
supor a seguinte descrio para o nosso problema envolvendo retas e pontos:
Problema A. necessrio um programa de computador que realize operaes
geomtricas envolvendo pontos e retas localizadas no plano cartesiano. O
programa deve permitir: calcular a distncia do ponto at a origem do plano
cartesiano; calcular a distncia entre dois pontos; dada a representao da reta
por dois pontos, calcular o ngulo de inclinao da reta, fornecer os
parmetros a e b correspondentes a equao da reta ax + b. Determinar a
distncia de uma reta a um ponto. Evidentemente, o programa deve permitir a
leitura e impresso de pontos e retas conforme a necessidade das operaes.

Com base na descrio acima podemos identificar a necessidade do TAD ponto
e do TAD Reta, bem como suas operaes. Essas operaes aparecem
sublinhadas no texto do problema e so apresentadas nas Figuras 1.7 e 1.8.



typedef struct {
float x, y;
}Ponto;
typedef struct {
Ponto a,b;
}Reta;
Operaes TAD Ponto:

- Calcular Distncia do ponto at
a Origem do plano cartesiano
- Calcular Distncia at outro
ponto
- Ler um ponto
- Imprimir um ponto
M. B. Costa Algoritmos e Estruturas de Dados
15





Figura 1.7: operaes do TAD Ponto para o problema A.











Figura 1.8: operaes do TAD Reta para o problema A.

Agora, considere que estejamos desenvolvendo um programa para o problema
abaixo:
Problema B. necessrio um programa de computador para apresentar
graficamente figuras geomtricas formadas por pontos e retas, usando o
monitor do computador como plano. O programa deve permitir: ler um ponto,
plotar um ponto na tela, ligar dois pontos por um segmento de reta; dada uma
reta passando por esse ponto, deslocar um outro ponto com base na equao
dessa reta; dada uma reta representada por dois pontos, plotar esta reta no
monitor; dada uma reta e um valor d, criar uma reta paralela reta dada a uma
distancia d da reta.
As operaes necessrias aos TAD Ponto e Reta neste problema so
apresentadas nas Figuras 1.9 e 1.10.





Figura 1.9: operaes do TAD Ponto para o problema B.


Operaes TAD Reta:

- Calcular o ngulo de inclinao
da reta
- Calcular os parmetros a e b
- Calcular a Distncia da reta a
at um ponto
- Ler uma reta representada por
dois pontos
- Imprimir uma reta representada
por dois pontos
Operaes TAD Ponto:

- Ler um ponto
- Plotar um ponto
- Ligar dois pontos
- Deslocar um ponto
Operaes TAD Reta:

- Ler uma Reta
- Plotar uma Reta
- Criar Reta Paralela
M. B. Costa Algoritmos e Estruturas de Dados
16




Figura 1.10: operaes do TAD Reta para o problema B.


Note que nos dois problemas foram definidos os tipos Ponto e Reta. No
entanto, a abstrao necessria difere de um problema para o outro,
interferindo na definio das operaes. Embora existam essas diferenas,
iremos sempre tentar criar abstraes mais genricas o quanto for possvel.
Quanto mais genrico um TAD, maior o um nmero de problemas em que
esse poder ser aplicado.

Embora as operaes no informem nada a respeito da representao interna
de um TAD, elas fornecem ao programador tudo o que ele precisa para
manipular o TAD. As operaes de um TAD especificam a sua interface com
o restante do programa. Isso significa que Qualquer ao relacionada ao
TAD deve ser feita mediante uma de suas operaes.
Temos como resultado prtico que o programador, ao usar o TAD, no vai
precisar se preocupar com sua implementao interna . Iremos agora analisar
esse aspecto considerando os TAD Ponto e Reta e o problema A.

Na implementao, ponto e reta foram definidos e implementados, originando
dois mdulos independentes: o mdulo Ponto e o mdulo Reta. Cada mdulo em
C normalmente implementado por dois arquivos: o arquivo .h e o arquivo .c.
No arquivo .c teremos a implementao das operaes do TAD e no arquivo .h
teremos a especificao da interface do TAD. A Figura 1.11 e a Figura 1.12
apresentam as interfaces dos mdulos Ponto e Reta, respectivamente.





Figura 1.11: Interface do TAD Ponto.






// interface do Tad Ponto: ponto.h
typedef struct ponto {
int x, int y;
}Ponto;
void lerPonto(Ponto *);
void distanciaOrigem(Ponto);
void distancia2Pontos(Ponto,Ponto);
// interface do Tad Reta: Reta.h
typedef struct reta {
struct ponto a,b;
} Reta;
void lerReta(Reta *);
void distanciaRetaPonto(Reta,Ponto);
void InclinacaoReta(Reta);
void equacaoReta(Reta);
M. B. Costa Algoritmos e Estruturas de Dados
17

Figura 1.12: Interface do TAD Reta.

Com a implementao dos TADs Ponto e Reta concludas e devidamente
testadas, qualquer outro mdulo do programa poder utilizar esses tipos por
meio das operaes definidas para os mesmos. Quando um mdulo A utiliza
um mdulo B em programao, dizemos que o mdulo A cliente do mdulo
B. Essa relao de clientela entre os mdulos (ou TADs) de um programa
pode ser representada graficamente por meio de um diagrama de estrutura
modular - DEM.
Diagrama de Estrutura Modular
Um diagrama de estrutura modular formado por retngulos e linhas
direcionadas relacionando os retngulos. Cada retngulo representa um
mdulo. As linhas direcionadas significam cliente de e indicam o
acionamento de operaes contidas no mdulo apontado pelo mdulo cliente.
Esses digramas tambm so chamados diagramas hierrquicos pois
apresentam a hierarquia dos mdulos, iniciando por um mdulo que inicia o
programa e aciona os demais mdulos.

Como exemplo, suponha que tenhamos tambm, junto aos mdulos Ponto e
Reta, um mdulo chamado principal. Esse mdulo cliente dos mdulos Ponto e
Reta. A Figura 1.13 a seguir ilustra o DEM deste programa. O mdulo que
inicia o programa o mdulo principal (e deve conter uma funo main() ). Ele
aciona as operaes tanto do mdulo ponto quanto do mdulo reta. Reta, por sua
vez, tambm cliente do mdulo ponto.





Figura 1.13: DEM com mdulos Ponto Reta e Principal.

A Figura 1.14 ilustra a implementao de um mdulo Principal. Note que a
nica forma de acesso aos TADs Ponto e Reta por meio das operaes
definidas em suas respectivas interfaces.

Use diagramas de estrutura modular sempre que for iniciar um novo projeto.
Defina os TADs e estabelea o relacionamento entre eles por meio de DEMs.
Junto s linhas, voc pode especificar as operaes do TAD que so
acionadas pelo cliente. Isso vai ajudar voc na especificao dos TADs.

Atividade 4
Implementar as operaes do TadPonto e do TadReta considerando o

Ponto Reta
Principal
M. B. Costa Algoritmos e Estruturas de Dados
18

enunciado do problema 1, da Seo 1.2.3 do texto, e desenvolver um
programa usando a funo principal (do quadro a seguir) de forma a testar as
operaes.



void principal() {
char opcao;
Ponto p1,p2;
Reta r1;
printf("1- Calcular Distncia at a origem.\n");
printf("2- Calcular Distncia entre pontos.\n");
printf("3- Calcular Distncia de uma reta a um
ponto.\n");
printf("4- Determinar inclinao da reta.\n");
printf("5- Determinar equao da reta.\n");
printf("0- Sair.\n");
printf("Informe a opo Desejada: ");
do{
opocao = getchar();
switch(opcao){
case '1': lerPonto(&p1);
distanciaOrigem(p1);
break;
case '2': lerPonto(&p1);
lerPonto(&p2);
distancia2Pontos(p1,p2);
break;
case '3': lerReta(&r1);
lerPonto(&p1);
distanciaRetaPonto(r1,p1);
break;
case '4': lerReta(&r1);
inclinacaoReta(r1);
break;
case '5': lerReta(&r1);
equacaoReta(r1);
break;
default: printf("Informe uma Opo Vlida.");

}
} while(opcao!='0');
}
int main(){
principal();
return 0;
}

Figura 1.14: Mdulo Principal para o Problema A.
At o momento, em nosso exemplo envolvendo Ponto e Reta, no abordamos
a questo de como as operaes sero implementadas propositalmente.
que at a parte que apresentamos do desenvolvimento no precisamos saber
mesmo. Voc por acaso lembra como se calcula a distncia entre dois
M. B. Costa Algoritmos e Estruturas de Dados
19

pontos? E a distncia entre uma reta e um ponto? Pois bem, o importante
que voc tenha compreendido a discusso feita e o exemplo dado, mesmo
sem saber responder essas duas perguntas. Assim espero!

1.2.4 Implementao de Tipos Abstratos de Dados
Um dos principais benefcios da abstrao de dados separar o
comportamento do TAD, especificado por meio da definio de suas
operaes, da sua implementao. Em nosso exemplo, o que definimos a
respeito dos TAD Ponto e Reta foi o seu comportamento, as suas operaes.
Nesta seo, discutiremos melhor como separar em um projeto a definio do
comportamento e da implementao de um TAD.

O projeto completo de um TAD consiste de dois passos:
1. Especificao - Consiste na especificao do comportamento do TAD;
2. Implementao Implementao das operaes e estruturas de dados.
Especificao
A especificao de um TAD descreve o que TAD faz, mas omite informaes
sobre como o mesmo implementado. Por omitir detalhes de implementao,
uma nica especificao permite muitas implementaes diferentes.
A especificao feita por meio da definio das operaes do TAD. Para
detalhar melhor cada uma destas operaes, devemos estabelecer, para cada
operao, dois elementos:
- Pr-condies: definem as condies necessrias para que a operao
possa ser realizada. Por exemplo, suponha que desejamos especificar o
TAD Conjunto com a operao listarConjunto. Uma pr-condio
para essa operao que o Conjunto no esteja vazio.
- Ps-condies: definem o estado do TAD aps a execuo da
operao,Por exemplo, suponha a operao inserirElemento no
TAD conjunto. Uma ps-condio para essa operao seria: elementos
no conjunto = elementos no conjunto + novo elemento. A Figura 1.15
ilustra a definio do TAD conjunto.









TAD Conjunto:
Operaes:
inserirElemento
- Pr-condies: conjunto cheio == FALSO
- Ps Condies: elementos no conjunto =
elementos do conjunto + novo elemento
listarConjunto
- Pr-Condies: conjuntoVazio == FALSO
- Ps-Condies: no h
M. B. Costa Algoritmos e Estruturas de Dados
20




Figura 1.15: Especificao do TAD Conjunto.
Implementao
Um TAD implementado por um mdulo de um programa. Uma nica
especificao permite diferentes implementaes para um mesmo TAD. Uma
implementao est correta se esta prov o comportamento especificado para o
TAD. Implementaes corretas podem diferir uma da outra, por exemplo, em
termos do algoritmo ou da estrutura de dados que elas usam. Essas diferenas
interferem na eficincia (desempenho em tempo de execuo, ou ocupao de
espao) apresentado pelo TAD para realizao das operaes.
Encapsulamento
Para uma abstrao funcionar corretamente, a sua implementao deve ser
encapsulada. Se a implementao for encapsulada, nenhum outro mdulo do
programa vai depender de detalhes de implementao do TAD.
Encapsulamento garante que mdulos do programa podem ser implementados
e re-implementados independentemente, sem afetar os outros mdulos do
programa.

O encapsulamento geralmente conseguido por meio da separao da interface
e da implementao do mdulo. Conforme j vimos anteriormente, em C a
implementao de um TAD por meio de um mdulo consiste em duas partes: a
especificao da interface do mdulo por meio do arquivo header ( com
extenso .h) e da implementao das operaes por meio de um arquivo com
extenso .c.
1.2.5 Avaliao de Implementaes de Tipos Abstratos de
Dados
fundamental para um programador saber criticar e avaliar a qualidade de
uma implementao! Uma implementao baseada em Abstrao de
Dados um indicativo de boa qualidade. Nesta Seo, discutiremos
elementos que permitem que voc verifique se uma implementao
realmente est de acordo com essa tcnica.

Embora a linguagem C no oferea um mecanismo que impea realmente que o
programador tenha acesso estrutura interna do TAD, esta uma regra
fundamental e deve ser respeitada pelo programador. Esta regra ou caracterstica
de TADs o encapsulamento, discutido na seo anterior. Dizemos que um
TAD encapsulado por suas operaes no sentido de que a estrutura interna do
TAD fica preservada e invisvel ao restante do programa. Violar essa regra
significa no usar corretamente a Abstrao de Dados.
Localidade
O maior benefcio do encapsulamento chama-se princpio da Localidade.
M. B. Costa Algoritmos e Estruturas de Dados
21

Esse princpio permite que um programa seja implementado, entendido e
modificado um mdulo de cada vez. A localidade aumenta a qualidade do
software que est sendo desenvolvido.

Dentre os benefcios oriundos do princpio da localidade temos:
1. O programador de uma abstrao sabe o que necessrio pelo que est
descrito na especificao. Dessa forma, ele no precisa interagir com
programadores de outros mdulos (ou, pelo menos, essa interao vai
ser bem limitada).
2. De forma anloga, o programador de um mdulo que usa a abstrao
sabe o que esperar desta abstrao, apenas pelo comportamento descrito
em sua especificao.

Uma ferramenta que pode contribuir para esse entendimento a
documentao do TAD. Ou seja, a explicao sobre o seu funcionamento e
sobre como utiliz-lo. Procure sempre fazer uma boa documentao do TAD.
Essa documentao pode vir como um documento parte que acompanha o
mdulo.

3. necessrio apenas o raciocnio local (por mdulo), para saber o que o
programa faz e se est fazendo a coisa certa. Para estudar e compreender
o programa, podemos dividi-lo em mdulos, e analisar um mdulo de
cada vez. Em cada caso, preocupamo-nos em saber se o mdulo faz o
que suposto que faa. Ou seja, se ele cumpre o que est na
especificao.
Pode-se assim limitar a ateno para um mdulo, ignorando tanto os
mdulos usados por este quanto os que o utilizam. Os mdulos que
utilizam o mdulo estudado podem ser ignorados porque dependem
apenas de sua especificao e no da sua implementao. Os mdulos
utilizados so ignorados, raciocinando-se sobre o que eles fazem
utilizando apenas sua especificao em vez de sua codificao. Com
isso, tem-se uma grande economia de esforo, dado que as
especificaes so muito menores que as implementaes. Observando-
se apenas as especificaes evita-se tambm um efeito cascata. Por
exemplo, se tivermos que olhar o cdigo do mdulo que utilizamos,
teremos que olhar tambm o cdigo dos mdulos que so utilizados
pelos mdulos que utilizamos e assim por diante.
4. Finalmente, a modificao do programa pode ser feita mdulo por
mdulo. Se uma abstrao particular necessita ser reimplementada para
prover um melhor desempenho, corrigir um erro ou prover uma nova
funcionalidade, o mdulo implementado anteriormente pode ser trocado
por uma nova implementao sem afetar os outros mdulos.
Prototipagem
Localidade tambm prov uma base firme para a prototipao ou
prototipagem. Um prottipo uma implementao inicial, rudimentar e
incompleta de um programa a ser desenvolvido. Se mantivermos o
M. B. Costa Algoritmos e Estruturas de Dados
22

princpio da localidade no desenvolvimento do prottipo, essa
implementao inicial pode ir sendo completada ou substituda por
implementaes melhores sem grande esforo nem re-trabalho.


Localidade tambm prov suporte para evoluo. Abstraes podem ser
utilizadas nesse caso para encapsular modificaes potenciais no
programa. Por exemplo, suponha que desejamos um programa para ser
executado em diferentes mquinas. Podemos tratar esse problema
inventando abstraes que escondam as diferenas entre as mquinas de
forma que, para mover o programa para uma mquina diferente, apenas
essas abstraes precisem ser reimplementadas. Um bom princpio de
projeto pensar sobre modificaes esperadas e organizar o
desenvolvimento utilizando abstraes que encapsulem as mudanas.

Domnio da complexidade
Os benefcios da localidade so particularmente importantes para a
abstrao de dados. Estruturas de dados so muitas vezes complicadas e a
viso mais abstrata mais simples provida pela especificao torna o resto
do programa mais simples. Ainda, mudanas nas estruturas de
armazenamento so uma das principais formas de evoluo de programas.
Portanto, os efeitos dessas mudanas devem ser minimizados encapsulando
essas estruturas de dados em abstraes de dados.

Se avaliarmos um programa segundo o critrio da abstrao de dados,
devemos observar os seguintes fatores:
1. Os TADs esto realmente encapsulados?
a. O entendimento de cada mdulo do programa independe dos
demais mdulos?
b. O efeito cascata evitado na depurao?
c. possvel reimplementar um mdulo sem afetar os outros?
2. Potenciais mudanas foram previstas no projeto do TAD?
3. Os TADs oferecem abstraes suficientemente simples das estruturas de
dados que encapsulam?

Atividade 5
Os cdigos a seguir especificam as interfaces de dois mdulos:
Aluno e Turma.
/**************** aluno.h *******************/
typedef struct aluno{
char nome[30];
int matricula;
int cdgcurso;
M. B. Costa Algoritmos e Estruturas de Dados
23

} Aluno;
void leAluno(Aluno *);
void imprimeAluno(Aluno);
void AlteraAluno(Aluno *);


/******************* turma.h *****************/
#include "aluno.h"
#define MAXTURMA 100
typedef struct turma {
int nalunos;
Aluno alunos[MAXTURMA];
}Turma;
void insereAluno(Turma *,Aluno);
/*insere o aluno passado como paramentro na
turma */
void localizaAluno(Turma *, char
*); /* localiza um aluno na turma pelo nome */
void imprimeTurma(Turma);
void atualizaAlunoDaTurma(Turma
*, char *);
Agora, suponha que tenhamos o seguinte mdulo principal,
utilizando esses mdulos:

/************ Modulo Principal **************/
#include "turma.h"
Turma turma1;

void principal(){
int opcao,i;
aluno a;
char nome[30];

do{
scanf("%d",&opcao);
switch(opcao){
case 1: /* cadastrar aluno */
lealuno(&a);
insereAluno(&turma1,a);
break;
}
case 2: /* imprimir os dados de um aluno
cujo nome xxx*/
scanf("%s",nome);
a= localizaAluno(&turma1, nome);
printf("%s - %d - %d",a.nome,
a.matricula,a.cdgcurso);
break;
case 3: /* imprimir turma */
for (i=0;i<turma.nalunos;i++)
imprimeAluno(turma.alunos[i]);
}
break;
case 4: /* alterar dados de um aluno */
scanf("%s",nome);
atualizaAlunoDaTurma(&turma1,
nome);
M. B. Costa Algoritmos e Estruturas de Dados
24

break;
}
}

}

Tarefas:
a) Critique a implementao do mdulo acima com base nos
critrios de avaliao de TADs discutidos acima.
b) Faa uma implementao da operao
atualizaAlunoDaTurma, respeitando os princpios de
programao baseada em tipos abstratos de dados.



Dijkstra (1930 2002) foi, sem dvida, um dos cientistas que mais
contriburam para o desenvolvimento da Programao de Computadores.
Terminamos este captulo com uma frase dele, que resume o conceito de
abstrao:
O propsito da abstrao no ser vaga, mas sim, criar um novo nvel
semntico no qual ela possa ser absolutamente precisa.
Edsger. W. Dijkstra, The Humble Programmer (O Programador Pobre),
Communications of the ACM, 15(10), 1972.
Reflita sobre isso!

S-ar putea să vă placă și