LISTAS
description
Transcript of LISTAS
![Page 1: LISTAS](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/1.jpg)
LISTASDilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello
![Page 2: LISTAS](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/2.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/3.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/4.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/5.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/6.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/7.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/8.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/9.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/10.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/11.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/12.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/13.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/14.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/15.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/16.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/17.jpg)
Lista Estática Sequencial em C++ Como ficaria essa implementação em C++?
Seria muito diferente?
![Page 18: LISTAS](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/18.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/19.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/20.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/21.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/22.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/23.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/24.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/25.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/26.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/27.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/28.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/29.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/30.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/31.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/32.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/33.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/34.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/35.jpg)
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](https://reader035.fdocuments.net/reader035/viewer/2022070410/56814623550346895db32c67/html5/thumbnails/36.jpg)
Perguntas?