listas dilvan moreira, parcialmente baseado em material do prof. ricardo campello

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

Upload: internet

Post on 16-Apr-2015

107 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

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

Page 2: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Linear

Estrutura de representação de informação em que os elementos são mantidos de forma linear, ou seja, dispostos um após o outro Ex. listas de nomes, de valores, de pessoas, etc.

Pode ser ordenada ou não Estruturação de informação em listas ocorre em vários domínios P. ex. lista telefônica

Page 3: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Linear

Operação Básica em Listas: Busca

por um elemento através de uma “chave” Ex. busca na lista telefônica: dado um nome, buscamos o telefone

Inserção e Remoção de elementos: Implementação depende da organização da lista manipulação distinta de listas ordenadas e não ordenadas

Page 4: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

TAD para Lista

Inicializar lista (p. ex. vazia): void Definir(Lista *L);

Inserir elemento: void Inserir(tipo_elem e, Lista *L);

Localizar a posição (na lista) de um elemento dado: int Localizar(tipo_elem e, Lista *L); retorna a posição do elemento na lista retorna um valor inválido caso ele não esteja na lista

Page 5: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

TAD para Lista

Acessar elemento em posição dada: tipo_elem Buscar(intp, Lista *L);

retorna o elemento da lista na posição fornecida sem alterá-la

se posição não existir, retorna um valor inválido

Eliminar elemento na posição dada: int Remover(intp, Lista *L);

Retorna 1 (true) se bem sucedida Retorna 0 (false) se posição dada é inválida

Obter número de elementos na lista: int Tamanho(Lista *L);

Page 6: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

TAD para Lista

Apagar a lista: void Apagar(Lista *L);

Destruir a lista: void Destruir(Lista *L);

lista não é mais acessível (só para implementações dinâmicas)

Obter posição seguinte à do último elemento: int Fim(Lista *L);

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

...

Page 7: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

EDs Estáticas para Listas Realizações Estáticas (vetores):

Seqüencial: seqüência de elementos disponíveis de forma consecutiva

Encadeada: seqüência de elementos disponíveis de forma não consecutiva

Page 8: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

EDs Dinâmicas para Listas Realizações Dinâmicas (ponteiros e memória): Simplesmente Encadeada:

Encadeamento de ponteiros unidirecional

Duplamente Encadeada: Encadeamento de ponteiros bidirecional

Cada realização possui vantagens e desvantagens

Page 9: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Estática Sequencial Implementação a Seguir:

Exemplo de Lista Estática Seqüencial em C

Projetada para Lista Não Ordenada Adaptação para lista ordenada como exercício no final

Page 10: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

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

typedef struct{ Tipo_1 chave; /* P. ex. int chave; */Tipo_2 info; /* P. ex. char info[50] */

} elem; /* Tipo do Elemento */

typedef struct{ int nelem;elem A[MAX+1];

} Lista; /* Tipo da Lista */

Lista L; /* Exemplo de Declaração*/

Page 11: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Estática Sequencialvoid Definir(Lista *L){ /* O(1) */

/* Define uma lista vazia */L->nelem= 0;L->A[0].chave = 0; /* Célula não utilizada */L->A[0].info[0] = '\0'; /* Célula não utilizada */

}

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

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

}

Page 12: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Estática Sequencialint Fim(Lista *L){ /* O(1) */

/* Retorna a posição após o último elemento da lista */return (L->nelem + 1);

}

bool Lista_vazia(Lista *L){ /* O(1) *//* Retorna true se lista vazia, false caso contrário */return (L->nelem == 0);

}

bool Lista_cheia(Lista *L){ /* O(1) */ /* Retorna true se lista cheia, false caso contrário */return (L->nelem == MAX);

}

Page 13: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Estática Sequencialbool Inserir(elem* x, int p, Lista *L){/* Insere elemento x na posição p da Lista L. Se a lista é tal que L=a1,a2,...,ap,...,an então L=a1,a2,...,ap-1,x,ap+1,...,an. Se p=Fim(L) então L=a1,a2,...,an,x. Devolve true se sucesso, false c.c. (L cheia ou não tem posição p). L não ordenada! */

int atual;if (Lista_cheia(L))

return FALSE; /* lista cheia */else if (p > Fim(L) || p < 1)

return FALSE; /* posição não existe */else {

for(atual = L->nelem; atual >= p; atual--)L->A[atual+1] = L->A[atual];

L->A[p]= *x;L->nelem++; return TRUE; /* inserção com sucesso */

} } /* O(L.nelem) no pior caso. Qual o pior caso? */

Page 14: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Estática Sequencialint Localizar(elem* x, Lista *L){ /* Retorna a posição de x na Lista. Se x ocorre mais de uma vez, retorna posição da 1a ocorrência. Se x não 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? */

Page 15: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Estática Sequencialbool igual(elem* a, elem* b) { /* Testa igualdade entre elementos por algum critério particular */

return (a->chave==b->chave);} /* O(1) */

elem* Buscar(int p, Lista *L){/* Retorna elem. da posição p, ou elem. inválido se p é inválida */

if (p >= Fim(L) || p < 1 || Lista_vazia(L))return x; /* retorna elemento inválido */

else return &(L->A[p]);} /* O(1) */

Page 16: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Estática Sequencialbool Remover(int p, Lista *L){/* Remove o elemento da posição p da Lista. Se L = a1,a2,...,an então tem-se a1,a2,...,ap-1,ap+1,...,an. Devolve true se sucesso, false c.c. (L não tem posição p, inclusive se p = Fim(L)) */

int atual;if(p >= Fim(L) || p < 1 || Lista_vazia(L)) return

FALSE;else {

for (atual = p+1; atual <= L->nelem; atual++) L->A[atual-1] = L->A[atual];

L->nelem--; } return TRUE;

} /* O(L.nelem) no pior caso. Qual o pior caso? */

.

Page 17: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Estática Sequencial em C++ Como ficaria essa implementação em C++?

Seria muito diferente?

Page 18: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Estática Sequencial Orig.#define MAX 100 /* Max. Tamanho da Lista */#define TRUE 1#define FALSE 0#define bool int

typedef struct{ char info[50]; /* P. ex. char info[50] */

} elem; /* Tipo do Elemento */

typedef struct{ int nelem;tipo_elem A[MAX+1];

} Lista; /* Tipo da Lista */

Lista L; /* Exemplo de Declaração*/

Page 19: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Estática Sequencial em C++#define MAX 100 /* Max. Tamanho da Lista */#define TRUE 1#define FALSE 0#define bool int

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 */

Page 20: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Estática Sequencial Orig.void Definir(Lista *L){ /* O(1) */

/* Define uma lista vazia */L->nelem= 0;L->A[0].info[0] = '\0'; /* Célula não utilizada */

}

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

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

}

Page 21: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Estática Sequencial em C++void Lista::Lista(){ /* O(1) */

/* Define uma lista vazia */nelem= 0;A[0].info[0] = '\0'; /* Célula não utilizada */

}

int Lista::Tamanho(){ /* O(1) */

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

}

Page 22: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Estática Sequencial Orig.int Fim(Lista *L){ /* O(1) */

/* Retorna a posição após o último elemento da lista */return (L->nelem + 1);

}

bool Lista_vazia(Lista *L){ /* O(1) *//* Retorna true se lista vazia, false caso contrário */return (L->nelem == 0);

}

bool Lista_cheia(Lista *L){ /* O(1) */ /* Retorna true se lista cheia, false caso contrário */return (L->nelem == MAX);

}

Page 23: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Estática Sequencial C++int List::Fim(){ /* O(1) */

/* Retorna a posição após o último elemento da lista */return (nelem + 1);

}

bool List::Lista_vazia(){ /* O(1) *//* Retorna true se lista vazia, false caso contrário */return (nelem == 0);

}

bool List::Lista_cheia(){ /* O(1) */ /* Retorna true se lista cheia, false caso contrário */return (nelem == MAX);

}

Page 24: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Estática Sequencial Orig.bool Inserir(elem* x, int p, Lista *L){/* Insere elemento x na posição p da Lista L. Se a lista é tal que L=a1,a2,...,ap,...,an então L=a1,a2,...,ap-1,x,ap+1,...,an. Se p=Fim(L) então L=a1,a2,...,an,x. Devolve true se sucesso, false c.c. (L cheia ou não tem posição p). L não ordenada! */

int atual;if (Lista_cheia(L))

return FALSE; /* lista cheia */else if (p > Fim(L) || p < 1)

return FALSE; /* posição não existe */else {

for(atual = L->nelem; atual >= p; atual--)L->A[atual+1] = L->A[atual];

L->A[p] = *x;L->nelem++; return TRUE; /* inserção com sucesso */

} } /* O(L.nelem) no pior caso. Qual o pior caso? */

Page 25: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Estática Sequencial C++bool List::Inserir(Elem* x, int p){/* Insere elemento x na posição p da Lista L. Se a lista é tal que L=a1,a2,...,ap,...,an então L=a1,a2,...,ap-1,x,ap+1,...,an. Se p=Fim(L) então L=a1,a2,...,an,x. Devolve true se sucesso, false c.c. (L cheia ou não tem posição p). L não ordenada! */

int atual;if (Lista_cheia())

return FALSE; /* lista cheia */else if (p > Fim() || p < 1)

return FALSE; /* posição não existe */else {

for(atual = nelem; atual >= p; atual--)A[atual+1] = A[atual];

A[p] = *x;nelem++; return TRUE; /* inserção com sucesso */

} } /* O(L.nelem) no pior caso. Qual o pior caso? */

Page 26: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Estática Sequencial Origint Localizar(elem* x, Lista *L){ /* Retorna a posição de x na Lista. Se x ocorre mais de uma vez, retorna posição da 1a ocorrência. Se x não 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? */

Page 27: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Estática Sequencial C++int List::Localizar(Elem* x){ /* Retorna a posição de x na Lista. Se x ocorre mais de uma vez, retorna posição da 1a ocorrência. Se x não 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? */

Page 28: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Estática Sequencial Origbool igual(elem* a, elem* b) { /* Testa igualdade entre elementos por algum critério particular */

return (strcmp(a->chave,b->chave)==0);} /* O(1) */

elem* Buscar(int p, Lista *L){/* Retorna elem. da posição p, ou elem. inválido se p é inválida */

if (p >= Fim(L) || p < 1 || Lista_vazia(L))return x; /* retorna elemento inválido */

else return L->A[p];} /* O(1) */

Page 29: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Estática Sequencial C++bool Elem::igual(elem* b) { /* Testa igualdade entre elementos por algum critério particular */

return (strcmp(info,b->info)==0);} /* O(1) */

Elem* List::Buscar(int p){/* Retorna elem. da posição p, ou elem. inválido se p é inválida */

if (p >= Fim() || p < 1 || Lista_vazia())return null; /* retorna inválido */

else return &A[p];} /* O(1) */

Page 30: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Estática Sequencial Origbool Remover(int p, Lista *L){/* Remove o elemento da posição p da Lista. Se L = a1,a2,...,an então tem-se a1,a2,...,ap-1,ap+1,...,an. Devolve true se sucesso, false c.c. (L não tem posição p, inclusive se p = Fim(L)) */

int atual;if(p >= Fim(L) || p < 1 || Lista_vazia(L)) return

FALSE;else {

for (atual = p+1; atual <= L->nelem; atual++) L->A[atual-1] = L->A[atual];

L->nelem--; } return TRUE;

} /* O(L.nelem) no pior caso. Qual o pior caso? */

.

Page 31: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Lista Estática Sequencial C++bool List::Remover(int p){/* Remove o elemento da posição p da Lista. Se L = a1,a2,...,an então tem-se a1,a2,...,ap-1,ap+1,...,an. Devolve true se sucesso, false c.c. (L não tem posição p, inclusive se p = Fim(L)) */

int atual;if(p >= Fim() || p < 1 || Lista_vazia()) return

FALSE;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? */

.

Page 32: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Checando

1. Modifique a operação Remover do TAD Lista Estática Seqüencial para que esta retorne o elemento removido e não um valor lógico.

2. Modifique a operação Localizar do TAD Lista Estática Seqüencial para que esta receba apenas a chave do elemento procurado e não o elemento todo.

3. Modifique a operação Localizar do TAD Lista Estática Seqüencial para que esta retorne um ponteiro para uma cópia do elemento localizado, cópia esta alocada dinamicamente em memória. Retorne NULL se o elemento não existir na lista.

4. Implemente o TAD Lista Estática Seqüencial em C, de forma modular, com módulos separados de interface (arquivo .h) e implementação (arquivo .c), e faça alguns testes.aula

Page 33: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Checando

5. Modifique a oImplemente uma nova operação de inserção para o TAD Lista Estática Seqüencial para substituir aquela que foi apresentada anteriormente nesses slides (Inserir). Essa nova operação 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 operação deve determinar a posição de inserção automaticamente, não recebê-la como parâmetro. Nesse exercício, faça isso percorrendo um a um os elementos da lista a partir do início (depois vide exercício 7).

Page 34: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Checando

6. Considerando que a operação de inserção utilizada no TAD Lista Estática Seqüencial é aquela implementada no exercício 5, reimplemente também a operação Localizar do TAD para que esta faça uso do fato da lista estar ordenada para realizar uma busca muito mais eficiente (binária) pelo elemento desejado.

6. Qual o tempo de execução assintótico (BIG-O) de pior caso da operação acima ? Qual o pior caso? Justifique.

7. Estando a nova operação de localização via busca binária do exercício 6 disponível, é possível utilizá-la para simplificar a implementação da operação de inserção ordenada do exercício 5? Explique.

Page 35: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Bibliografia

N. Ziviani, Projeto de Algoritmos, Thomson, 2a. Edição, 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

Page 36: LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello

Perguntas?