Você está na página 1de 22

IN F 1 1 2 : P ro g ra m a o II

A u la 1 1

Tipo Abstrato de Dados

F b io R . C e rqu e ira , U F V , DP I, frc e rqu e ira @g m a il.c o m


T ipo a b s tra to de da do s

Toda linguagem de alto nvel moderna deve permitir que o


programador declare novos tipos de modo a possibilitar uma
modelagem mais prxima da realidade. Em C++ um novo tipo
declarado quando usamos a palavra chave typedef ou
struct.
typedef unsigned int Natural; //criando novo tipo
struct Racional // criando novo tipo
{
int num;
int den;
};

Natural x; // usando novo tipo


Racional y; // usando novo tipo
T ipo a b s tra to de da do s

Esta facilidade permite que programadores possam


desenvolver programas mais expressivos. No entanto, este
recurso possui limitaes, tanto no que se refere
expressividade como na organizao de programas:
Certos tipos de dados no podem ser declarados usando
este recurso. Por exemplo, no podemos declarar um tipo
que s aceite nmeros pares.
typedef int Par;

int main()
{
Par p;
p = 1; // No ocorre erro
...
}
T ipo a b s tra to de da do s

medida que o programa cresce e vrias rotinas passam a


utilizar os tipos declarados, torna-se difcil qualquer
alterao nos tipos, uma vez que pode afetar todos os
trechos de programas onde variveis dos tipos alterados so
utilizadas.
T ipo a b s tra to de da do s

Para contornar este problema surgiu um novo conceito


denominado de Tipo Abstrato de Dados (TAD).

O TAD um modelo independente de qualquer abordagem


computacional (no leva em conta possveis implementaes) e
que especifica um conjunto de dados e operaes que podem
ser executadas sobre estes dados.

A implementao de TADs em programao tem como


objetivo o estabelecimento de uma metodologia que reduza a
informao necessria para a criao/programao de um
algoritmo atravs da abstrao das variveis envolvidas em
uma nica entidade fechada (encapsulamento), com operaes
prprias sua natureza.
T ipo a b s tra to de da do s

Um exemplo prtico para entender a importncia dos TADs


o de representao de dados de estudantes num programa.

Em um projeto anterior teoria de TAD, um estudante seria


representado por variveis soltas, como seu nome, sua idade e
sua matrcula, que seriam utilizadas em separado, sem que
houvesse uma ligao lgica entre elas. Alm disto, o
programador teria que saber que tais variveis soltas estariam
relacionadas entidade estudante.

Com o conceito de TAD, a ideia que no haja nome, idade e


matrcula soltos pelo programa. A abordagem seria pela
criao do tipo estudante que descrevesse estes dados e
ainda que houvesse operaes prprias ao tipo estudante.
T ipo a b s tra to de da do s

A ideia que o programador s faa a manipulao dos dados


via operaes para este fim e que os detalhes destas operaes
lhe sejam transparentes (ocultao de informao).

Imaginemos ento um TAD Estudante com os dados:


nome, idade, matrcula.

e as operaes:
maior_de_idade: diz se estudante maior de idade ou
no;
valida_matricula: diz se nmero de matrcula vlido
ou no.
T ipo a b s tra to de da do s

Vamos agora dar uma ideia da implementao deste modelo


com os recursos de programao que conhecemos.

Com o que sabemos, TADs so implementados utilizando-se


tipos compostos (structs) e funes para representar as
operaes do modelo. Assim, poderamos ter:

struct Estudante {
char nome[80];
short int idade;
int matricula;
};

bool maiorDeIdade(Estudante &e);


bool validaMatricula(Estudante &e);
T ipo a b s tra to de da do s

Um outro exemplo poderia ser a representao de nmeros


racionais. Um nmero racional representado pela razo de dois
nmeros inteiros. Algumas operaes comuns para nmeros racionais
so soma e teste de igualdade. Para implementar o TAD nmero
racional vamos incluir as operaes acima mais algumas outras
teis no programa.
Arquivo racional.h
struct Racional {
int num;
int den;
};

Racional somaRacional(Racional r1, Racional r2);


bool igualRacional(Racional r1, Racional r2);
int getNumRacional(Racional r);
int getDenRacional(Racional r);
Racional criaRacional(int num, int den );
T ipo a b s tra to de da do s

Arquivo racional.cpp
#include racional.h

Racional criaRacional(int num, int den ) {


Racional r;
r.num = num;
r.den = den==0?1:den;
return r;
}

Racional somaRacional(Racional r1, Racional r2) {


Racional r;
r.num = r1.num*r2.den + r2.num*r1.den;
r.den = r1.den*r2.den;
return r;
}
. . .
T ipo a b s tra to de da do s

. . .
bool igualRacional(Racional r1, Racional r2){
if (r1.num*r2.den == r1.den*r2.num)
return true;
return false;
}

int getNumRacional(Racional r) {
return r.num;
}

int getDenRacional(Racional r) {
return r.den;
}
T ipo a b s tra to de da do s
A questo que o TAD somente um modelo. Ao implement-lo,
no h nenhuma segurana de que as operaes e regras de operao
desejadas para este tipo sejam respeitadas.

No existem recursos para ocultar a estrutura de dados de


procedimentos que no foram projetados para a sua manipulao.

No existe uma forma de relacionar explicitamente as estruturas de


dados com os procedimentos que as manipulam.

Veremos mais frente como a programao orientada a objetos


surge para sanar estes problemas, alm de outras vantagens que
veremos no devido tempo.

Por ora, vejamos um outro TAD muito importante em cincia da


computao, o TAD lista.
T A D lis ta

Implementaes do TAD lista compem provavelmente o tipo de


estrutura de dados mais utilizado em programao, uma vez que
muitas situaes aparecem naturalmente na forma de lista.

Uma lista uma coleo L:[a1, a2, ..., an], n > 0, cuja propriedade
estrutural baseia-se apenas na posio relativa dos elementos, que so
dispostos linearmente.

Se n=0, dizemos que a lista vazia; caso contrrio, so vlidas as


seguintes propriedades:
a1 o primeiro elemento de L;
an o ltimo elemento de L;
ak, 1<k<n, precedido pelo elemento ak-1 e seguido por ak+1 em L.
T A D lis ta

Em outras palavras, a caracterstica fundamental de uma


lista linear o sentido de ordem unidimensional dos
elementos que a compem.

Dentre as vrias operaes comuns de um TAD lista,


podemos citar as seguintes como sendo as principais:
Insero de um elemento;
Remoo de um elemento;
Localizao de um elemento.

Ao implementar o TAD lista, a operao de inicializao


tambm importante. Outra operao que poder ser
necessria a de finalizao ou destruio (liberao da
memria utilizada).
L is t a s e s t tic a s c o n tg u a s

Vejamos ento uma das implementaes mais simples do


TAD lista, a estrutura de dados: lista esttica contgua.

Listas estticas so tipicamente implementadas atravs de


arranjos.

Em uma lista esttica contgua, o sucessor de um elemento


ocupa posio fsica subsequente na memria.

Ento, o arranjo associa o elemento ai com o ndice i


(mapeamento sequencial).
L is t a s e s t tic a s c o n tg u a s

Caractersticas de lista esttica contgua:

Elementos armazenados fisicamente em posies


consecutivas;

A insero de um elemento na posio i causa o


deslocamento para a direita do elemento ai ao ltimo;

A eliminao do elemento ai requer o deslocamento


para a esquerda do ai+1 ao ltimo.
L is t a s e s t tic a s c o n tg u a s

Vantagem:
Acesso direto indexado a qualquer elemento da lista.

Desvantagem:
Movimentao quando um elemento
eliminado/inserido;
Tamanho mximo pr-estimado (esta uma desvantagem
de qualquer lista esttica, na verdade).

Quando usar:
Listas pequenas;
Tamanho mximo bem definido;
Insero/remoo no fim da lista.
L is t a s e s t tic a s c o n tg u a s

Mostraremos agora uma implementao em C++ deste


tipo de lista. Para fins didticos, descreveremos uma
estrutura de dados para representar lista de inteiros, mas,
obviamente, a estrutura ensinada pode ser empregada para
qualquer tipo de dado vlido, nativo ou criado pelo
programador.
L is t a s e s t tic a s c o n tg u a s

#define MAX 50
struct Lista {
int elem[MAX]; // arranjo para os elementos.
int posUlt; // posicao do ultimo elemento.
};

// Inicializa lista como vazia


void fazListaVazia(Lista &l) {
l.posUlt = -1;
}

// Testa se lista estah vazia


bool listaVazia(Lista &l) {
return (l.posUlt == -1);
}

bool listaCheia(Lista &l) {


return (l.posUlt == MAX-1);
}
L is t a s e s t tic a s c o n tg u a s

bool insere(Lista &l, int e, int i) {


// Insere o elemento e na posicao i.
// Retorna true para sucesso e false para falha.
int j;
// Se hah espaco e posicao eh valida
if ( !listaCheia(l) && i >= 0 && i <= l.posUlt+1 ) {
for (j = l.posUlt+1; j >= i+1; j--) // shiftando
l.elem[j] = l.elem[j-1];
l.elem[i] = e;
l.posUlt++;
return true;
}
return false;
}
L is t a s e s t tic a s c o n tg u a s

bool remove(Lista &l, int i) {


// Remove o elemento da posicao i.
// Retorna true para sucesso e false para falha.
int j;
// se a posicao para remover for valida
if (i >= 0 && i <= l.posUlt) {
for (j=i; j <= l.posUlt-1; j++)
l.elem[j] = l.elem[j+1];
l.posUlt--;
return true;
}
return false;
}
E x e rc c io

Implemente as operaes: tamanho (retorna a


quantidade de elementos da lista), localiza (retorna a
posio do elemento procurado na lista) e imprime
(imprime os elementos da lista).