Estruturas de Dados 2004/2005
Pesquisas numa Lista Ligada simples
• Uma pesquisa é uma travessia da lista, até à identificação de um certo elemento ou até
esgotar a lista.
Por exemplo, se quisermos identificar, numa dada lista, o elemento cujo campo de
informação, info, contém estainfo, poderı́amos fazer:
antp = NULL; p = ponta;
while(p->info != estainfo){
ant = p; p = p->prox;
}
{ p aponta o elemento que contém estainfo e ant aponta o elemento anterior a este }
No entanto, se estainfo não “pertencer” à lista, ocorreria um erro: no final da lista,
p==NULL e tentar-se-ia aceder ao campo p− >info ?!!!
Este caso é facilmente corrigido em C usando, para cabeça do ciclo de pesquisa, a instrução:
antp = NULL; p = ponta;
while((p != NULL) && (p->info != estainfo)){
ant = p; p = p->prox;
}
devido à avaliação condicional da linguagem C.
1
Estruturas de Dados 2004/2005
Exemplo de aplicação: remover o elemento com estainfo da lista
/* pesquisar:
devolve um apontador para o elemento anterior ao procurado */
#define TRUE 1
#define FALSE 0
typedef int BOOL;
. . .
BOOL remover(Item estainfo, Seta *ponta){
Seta antp, p;
BOOL pesquisar(), achou = FALSE;
if(achou = pesquisar(estainfo, *ponta, &antp)){
if(antp == NULL){
// estainfo no 1o. elemento
p = ponta;
*ponta = ponta->prox;
}else{
// Caso geral
p = ant->prox;
antp->prox = p->prox;
}
Libertar(&p);
// Liberta a caixa e anula o ponteiro p
}
return achou;
}
2
Estruturas de Dados 2004/2005
Construção (Sequencial) de uma Lista Ligada
Exemplo: construir uma lista de nomes lidos a partir de um ficheiro
Hipótese 1: com inserção à cabeça
Seta
Seta
BOOL
Item
construirLista0(File fich){
novo, ponta;
fimdoficheiro();
ler info();
ponta = NULL;
while(!fimdoficheiro(fich)){
novo = (Seta) malloc(sizeof(no));
novo->val = ler_info(fich);
novo->prox = ponta;
ponta = novo;
}
return ponta;
}
3
Estruturas de Dados 2004/2005
4
Construção (Sequencial) de uma Lista Ligada
Notas sobre construirLista0():
• A inicialização de ponta a NULL serve dois propósitos:
1. coloca o NULL como valor de ”fim de lista”;
2. caso não existam nomes no ficheiro, devolve a lista vazia.
• os elementos da lista devolvida aparecem por sequência inversa daquela que
apresentam no ficheiro
Hipótese 2: com inserção no final
Seta
Seta
BOOL
Item
construirLista1(File fich){
novo, ponta, fim;
//fim, ponteiro auxiliar para o ultimo elemento
fimdoficheiro();
ler info();
if(fimdoficheiro)
ponta = NULL;
else{
// inicializar a lista com o primeiro elemento
ponta = (Seta) malloc(sizeof(no));
ponta->val = ler_info(fich);
ponta->prox = NULL;
fim = ponta;
Estruturas de Dados 2004/2005
// caso geral
while(!fimdoficheiro(fich)){
novo = (Seta) malloc(sizeof(no));
novo->val = ler_info(fich);
novo->prox = NULL;
fim = fim->prox = novo;
}
}// final do else
return ponta;
}// construirLista1
Notas sobre construirLista1():
• os elementos da lista devolvida aparecem pela mesma sequência daquela que
apresentam no ficheiro
• a pesquisa de fim de lista foi evitada usando o ponteiro auxiliar fim
• o tratamento especial do primeiro elemento (bem como do if inicial) poderia ser
evitado usando uma sentinela (nó provisório), que seria eliminado antes da
devolução da lista.
5
Estruturas de Dados 2004/2005
Hipótese 3: com inserção no final e estratégia recorrente
void JuntarNoRec(Item valor, Seta *pt){
if(*pt == NULL){
// fim de lista, colocar novo elemento
ponta = (Seta) malloc(sizeof(no));
ponta->val = valor;
ponta->prox = NULL;
}else JuntarNoRec(valor, &((*pt)->prox))
}
Seta
Seta
BOOL
Item
construirLista2(File fich){
ponta;
fimdoficheiro();
ler info();
ponta = NULL;
while(!fimdoficheiro(fich)) JuntarNoRec(ler_info(fich), &ponta);
return ponta;
}// construirLista2
Notas sobre construirLista2():
• A construção trabalha devido à passagem do parâmetro ponta por referência
• Em cada nova inserção está a ser realizada uma travessia completa da lista pelo
que esta versão é extremamente ineficiente
6
Download

Pesquisas numa Lista Ligada simples