Você está na página 1de 36

LISTAS

Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Linear

Estrutura de representao de informao em que os elementos so mantidos de forma linear, ou seja, dispostos um aps o outro
Ex.

listas de nomes, de valores, de pessoas, etc.

Pode ser ordenada ou no Estruturao de informao em listas ocorre em vrios domnios


P.

ex. lista telefnica

Lista Linear
Operao Bsica em Listas: Busca
por

um elemento atravs de uma chave

Ex. busca na lista telefnica: dado um nome, buscamos o telefone

Insero e Remoo de elementos:


Implementao
manipulao

depende da organizao da lista

distinta de listas ordenadas e no

ordenadas

TAD para Lista

Inicializar lista (p. ex. vazia):


void

Definir(Lista *L);
Inserir(tipo_elem e, Lista *L);

Inserir elemento:
void

Localizar a posio (na lista) de um elemento dado:


int

Localizar(tipo_elem e, Lista *L); a posio do elemento na lista retorna um valor invlido caso ele no esteja na lista

retorna

TAD para Lista

Acessar elemento em posio dada:

tipo_elem Buscar(intp, Lista *L);


retorna o elemento da lista na posio fornecida sem alter-la se posio no existir, retorna um valor invlido

Eliminar elemento na posio dada:

int Remover(intp, Lista *L);


Retorna 1 (true) se bem sucedida Retorna 0 (false) se posio dada invlida

Obter nmero de elementos na lista:

int Tamanho(Lista *L);

TAD para Lista

Apagar a lista:
void

Apagar(Lista *L);
Destruir(Lista *L);

Destruir a lista:
void
lista

no mais acessvel (s para implementaes dinmicas)

Obter posio seguinte do ltimo elemento:


int

Fim(Lista *L);

Verificar se lista est vazia, verificar se est cheia... ...

EDs Estticas para Listas

Realizaes Estticas (vetores):


Seqencial:
seqncia

de elementos disponveis de forma consecutiva

Encadeada:
seqncia

de elementos disponveis de forma no consecutiva

EDs Dinmicas para Listas

Realizaes Dinmicas (ponteiros e memria):


Simplesmente

Encadeada:
de ponteiros unidirecional

Encadeamento

Duplamente

Encadeada:
de ponteiros bidirecional

Encadeamento

Cada realizao possui vantagens e desvantagens

Lista Esttica Sequencial

Implementao a Seguir:
Exemplo

de Lista Esttica Seqencial em C Projetada para Lista No Ordenada


Adaptao

para lista ordenada como exerccio no final

Lista Esttica Sequencial


#define #define #define #define MAX 100 TRUE 1 FALSE 0 bool int /* Max. Tamanho da Lista */

typedef struct{ Tipo_1 chave; Tipo_2 info; } elem; typedef struct{ int nelem; elem A[MAX+1]; } Lista; Lista L;

/* P. ex. int chave; */ /* P. ex. char info[50] */ /* Tipo do Elemento */

/* Tipo da Lista */ /* Exemplo de Declarao*/

Lista Esttica Sequencial


void Definir(Lista *L){ /* O(1) */ /* Define uma lista vazia */ L->nelem= 0; L->A[0].chave = 0; /* Clula no utilizada */ L->A[0].info[0] = '\0'; /* Clula no utilizada */

}
int Tamanho(Lista *L){ /* O(1) */

/* Retorna o tamanho da Lista (0 caso vazia) */ return L->nelem; }

Lista Esttica Sequencial


int Fim(Lista *L){ /* O(1) */ /* Retorna a posio aps o ltimo elemento da lista */ return (L->nelem + 1); } bool Lista_vazia(Lista *L){ /* O(1) */ /* Retorna true se lista vazia, false caso contrrio */ return (L->nelem == 0); } bool Lista_cheia(Lista *L){ /* O(1) */ /* Retorna true se lista cheia, false caso contrrio */ return (L->nelem == MAX); }

Lista Esttica Sequencial


bool Inserir(elem* x, int p, Lista *L){ /* Insere elemento x na posio p da Lista L. Se a lista tal que L=a1,a2,...,ap,...,an ento L=a1,a2,...,ap-1,x,ap+1,...,an. Se p=Fim(L) ento L=a1,a2,...,an,x. Devolve true se sucesso, false c.c. (L cheia ou no tem posio p). L no ordenada! */ int atual; if (Lista_cheia(L)) return FALSE; /* lista cheia */ else if (p > Fim(L) || p < 1) return FALSE; /* posio no existe */ else { for(atual = L->nelem; atual >= p; atual--) L->A[atual+1] = L->A[atual]; L->A[p]= *x; L->nelem++; return TRUE; /* insero com sucesso */ } } /* O(L.nelem) no pior caso. Qual o pior caso? */

Lista Esttica Sequencial


int Localizar(elem* x, Lista *L){ /* Retorna a posio de x na Lista. Se x ocorre mais de uma vez, retorna posio da 1a ocorrncia. Se x no ocorre, retorna 0 */ int atual = 1; if (!Lista_vazia(L)){ while(atual <= L->nelem){ if(igual(&A[atual], x)) /* iguais ?*/ return atual; /* retorno sucesso */ else atual++; } } return 0; /* retorno em insucesso ou lista vazia */ } /* O(L.nelem) no pior caso. Qual o pior caso? */

Lista Esttica Sequencial


bool igual(elem* a, elem* b) { /* Testa igualdade entre elementos por algum critrio particular */ return (a->chave==b->chave); /* O(1) */

elem* Buscar(int p, Lista *L){ /* Retorna elem. da posio p, ou elem. invlido se p invlida */ if (p >= Fim(L) || p < 1 || Lista_vazia(L)) return x; /* retorna elemento invlido */ else return &(L->A[p]); /* O(1) */

Lista Esttica Sequencial


bool Remover(int p, Lista *L){ /* Remove o elemento da posio p da Lista. Se L = a1,a2,...,an ento tem-se a1,a2,...,ap-1,ap+1,...,an. Devolve true se sucesso, false c.c. (L no tem posio p, inclusive se p = Fim(L)) */ int atual; if(p >= Fim(L) || p < 1 || Lista_vazia(L)) return else { atual++) for (atual = p+1; atual <= L->nelem;

FALSE;

L->A[atual-1] = L->A[atual]; L->nelem--; } return TRUE; } /* O(L.nelem) no pior caso. Qual o pior caso? */

Lista Esttica Sequencial em C++

Como ficaria essa implementao em C++? Seria muito diferente?

Lista Esttica Sequencial Orig.


#define #define #define #define MAX 100 TRUE 1 FALSE 0 bool int /* Max. Tamanho da Lista */

typedef struct{ char info[50]; } elem;

/* P. ex. char info[50] */ /* Tipo do Elemento */

typedef struct{ int nelem; tipo_elem A[MAX+1]; } Lista; /* Tipo da Lista */ Lista L; /* Exemplo de Declarao*/

Lista Esttica Sequencial em C++


#define #define #define #define MAX 100 TRUE 1 FALSE 0 bool int /* Max. Tamanho da Lista */

class Elem { char info[50];

/* P. ex. char info[50] */

} /* Tipo do Elemento */ class List { int nelem; tipo_elem A[MAX+1]; } /* Tipo da Lista */

Lista Esttica Sequencial Orig.


void Definir(Lista *L){ /* O(1) */ /* Define uma lista vazia */ L->nelem= 0; L->A[0].info[0] = '\0'; /* Clula no utilizada */ }

int Tamanho(Lista *L){

/*

O(1)

*/

/* Retorna o tamanho da Lista (0 caso vazia) */ return L->nelem; }

Lista Esttica Sequencial em C++


void Lista::Lista(){ /* O(1) */ /* Define uma lista vazia */ nelem= 0; A[0].info[0] = '\0'; /* Clula no utilizada */ }

int Lista::Tamanho(){

/*

O(1)

*/

/* Retorna o tamanho da Lista (0 caso vazia) */ return nelem; }

Lista Esttica Sequencial Orig.


int Fim(Lista *L){ /* O(1) */ /* Retorna a posio aps o ltimo elemento da lista */ return (L->nelem + 1); } bool Lista_vazia(Lista *L){ /* O(1) */ /* Retorna true se lista vazia, false caso contrrio */ return (L->nelem == 0); } bool Lista_cheia(Lista *L){ /* O(1) */ /* Retorna true se lista cheia, false caso contrrio */ return (L->nelem == MAX); }

Lista Esttica Sequencial C++


int List::Fim(){ /* O(1) */ /* Retorna a posio aps o ltimo elemento da lista */ return (nelem + 1); } bool List::Lista_vazia(){ /* O(1) */ /* Retorna true se lista vazia, false caso contrrio */ return (nelem == 0); } bool List::Lista_cheia(){ /* O(1) */ /* Retorna true se lista cheia, false caso contrrio */ return (nelem == MAX); }

Lista Esttica Sequencial Orig.


bool Inserir(elem* x, int p, Lista *L){ /* Insere elemento x na posio p da Lista L. Se a lista tal que L=a1,a2,...,ap,...,an ento L=a1,a2,...,ap-1,x,ap+1,...,an. Se p=Fim(L) ento L=a1,a2,...,an,x. Devolve true se sucesso, false c.c. (L cheia ou no tem posio p). L no ordenada! */ int atual; if (Lista_cheia(L)) return FALSE; /* lista cheia */ else if (p > Fim(L) || p < 1) return FALSE; /* posio no existe */ else { for(atual = L->nelem; atual >= p; atual--) L->A[atual+1] = L->A[atual]; L->A[p] = *x; L->nelem++; return TRUE; /* insero com sucesso */ } } /* O(L.nelem) no pior caso. Qual o pior caso? */

Lista Esttica Sequencial C++


bool List::Inserir(Elem* x, int p){ /* Insere elemento x na posio p da Lista L. Se a lista tal que L=a1,a2,...,ap,...,an ento L=a1,a2,...,ap-1,x,ap+1,...,an. Se p=Fim(L) ento L=a1,a2,...,an,x. Devolve true se sucesso, false c.c. (L cheia ou no tem posio p). L no ordenada! */ int atual; if (Lista_cheia()) return FALSE; /* lista cheia */ else if (p > Fim() || p < 1) return FALSE; /* posio no existe */ else { for(atual = nelem; atual >= p; atual--) A[atual+1] = A[atual]; A[p] = *x; nelem++; return TRUE; /* insero com sucesso */ } } /* O(L.nelem) no pior caso. Qual o pior caso? */

Lista Esttica Sequencial Orig


int Localizar(elem* x, Lista *L){ /* Retorna a posio de x na Lista. Se x ocorre mais de uma vez, retorna posio da 1a ocorrncia. Se x no ocorre, retorna 0 */ int atual = 1; if (!Lista_vazia(L)){ while(atual <= L->nelem){ if(igual(&L->A[atual], x)) return atual; /* retorno em sucesso */ else atual++; } } return 0; /* retorno em insucesso ou lista vazia */ } /* O(L.nelem) no pior caso. Qual o pior caso? */

Lista Esttica Sequencial C++


int List::Localizar(Elem* x){ /* Retorna a posio de x na Lista. Se x ocorre mais de uma vez, retorna posio da 1a ocorrncia. Se x no ocorre, retorna 0 */ int atual = 1; if (!Lista_vazia()){ while(atual <= nelem){ if(A[atual].Igual(x)) return atual; /* retorno em sucesso */ else atual++; } } return 0; /* retorno em insucesso ou lista vazia */ } /* O(L.nelem) no pior caso. Qual o pior caso? */

Lista Esttica Sequencial Orig


bool igual(elem* a, elem* b) { /* Testa igualdade entre elementos por algum critrio particular */ return (strcmp(a->chave,b->chave)==0); /* O(1) */

elem* Buscar(int p, Lista *L){ /* Retorna elem. da posio p, ou elem. invlido se p invlida */ if (p >= Fim(L) || p < 1 || Lista_vazia(L)) return x; /* retorna elemento invlido */ else return L->A[p]; /* O(1) */

Lista Esttica Sequencial C++


bool Elem::igual(elem* b) { /* Testa igualdade entre elementos por algum critrio particular */ return (strcmp(info,b->info)==0); /* O(1) */

Elem* List::Buscar(int p){ /* Retorna elem. da posio p, ou elem. invlido se p invlida */ if (p >= Fim() || p < 1 || Lista_vazia()) return null; /* retorna invlido */ else return &A[p]; /* O(1) */

Lista Esttica Sequencial Orig


bool Remover(int p, Lista *L){ /* Remove o elemento da posio p da Lista. Se L = a1,a2,...,an ento tem-se a1,a2,...,ap-1,ap+1,...,an. Devolve true se sucesso, false c.c. (L no tem posio p, inclusive se p = Fim(L)) */ int atual; if(p >= Fim(L) || p < 1 || Lista_vazia(L)) return else { atual++) for (atual = p+1; atual <= L->nelem;

FALSE;

L->A[atual-1] = L->A[atual]; L->nelem--; } return TRUE; } /* O(L.nelem) no pior caso. Qual o pior caso? */

Lista Esttica Sequencial C++


bool List::Remover(int p){ /* Remove o elemento da posio p da Lista. Se L = a1,a2,...,an ento tem-se a1,a2,...,ap-1,ap+1,...,an. Devolve true se sucesso, false c.c. (L no tem posio p, inclusive se p = Fim(L)) */ int atual; if(p >= Fim() || p < 1 || Lista_vazia()) return else { for (atual = p+1; atual <= nelem; atual++) A[atual-1] = A[atual]; nelem--; } return TRUE; } /* O(L.nelem) no pior caso. Qual o pior caso? */

FALSE;

Checando
1.

2.

3.

4.

Modifique a operao Remover do TAD Lista Esttica Seqencial para que esta retorne o elemento removido e no um valor lgico. Modifique a operao Localizar do TAD Lista Esttica Seqencial para que esta receba apenas a chave do elemento procurado e no o elemento todo. Modifique a operao Localizar do TAD Lista Esttica Seqencial para que esta retorne um ponteiro para uma cpia do elemento localizado, cpia esta alocada dinamicamente em memria. Retorne NULL se o elemento no existir na lista. Implemente o TAD Lista Esttica Seqencial em C, de forma modular, com mdulos separados de interface (arquivo .h) e implementao (arquivo .c), e faa alguns testes.aula

Checando
5.

Modifique a oImplemente uma nova operao de insero para o TAD Lista Esttica Seqencial para substituir aquela que foi apresentada anteriormente nesses slides (Inserir). Essa nova operao deve inserir o novo elemento de forma a manter sempre a lista ordenadapelas chaves dos seus elementos.
5.

OBS: Como a lista deve ser mantida ordenada, essa operao deve determinar a posio de insero automaticamente, no receb-la como parmetro. Nesse exerccio, faa isso percorrendo um a um os elementos da lista a partir do incio (depois vide exerccio 7).

Checando
6.

Considerando que a operao de insero utilizada no TAD Lista Esttica Seqencial aquela implementada no exerccio 5, reimplemente tambm a operao Localizar do TAD para que esta faa uso do fato da lista estar ordenada para realizar uma busca muito mais eficiente (binria) pelo elemento desejado.
6.

Qual o tempo de execuo assinttico (BIG-O) de pior caso da operao acima ? Qual o pior caso? Justifique.

7.

Estando a nova operao de localizao via busca binria do exerccio 6 disponvel, possvel utiliz-la para simplificar a implementao da operao de insero ordenada do exerccio 5? Explique.

Bibliografia

N. Ziviani, Projeto de Algoritmos, Thomson, 2a. Edio, 2004 A. M. Tenembaum et al., Data Structures Using C, Prentice-Hall, 1990 J. L. Szwarcfiter & L. Markenzon, Estruturas de Dados e seus Algoritmos, LTC, 1994

Perguntas?

Você também pode gostar