Dando continuidade ao estuda da estrutura lista encadeada em nosso Curso de Programação C, nesta aula vamos aprender como buscar um elemento em uma lista encadeada.
Para buscar um elemento na lista encadeada é necessário percorrer a lista comparando o valor guardado por cada nó com o valor procurado. A repetição poderá finalizar por dois motivos: quando encontrarmos o valor procurado ou quando o ponteiro para a lista for null, indicando que chegamos ao final da lista, neste caso o elemento procurado não existe na lista.
Assim, basta verificar o ponteiro para a lista quando a repetição terminar. Se ele for diferente de nulo, então encontramos o nó que possui o valor procurado.
É comum encontrar funções / procedimentos recursivos para realizar uma busca. Contudo, para evitar o uso da pilha de recursão, apresentamos a seguir uma versão interativa.
/* Função para buscar um elemento na lista */ No* buscar(No **lista, int num){ No *aux, *no = NULL; aux = *lista; while(aux && aux->valor != num) aux = aux->proximo; if(aux) no = aux; return no; }
Código completo em C para testar uma Lista Simplesmente Encadeada
/* Código escrito por Wagner Gaspar Agosto de 2021 Aula 252: Lista Simplesmente Encadeada Busca SEM a estrutura lista */ typedef struct no{ int valor; struct no *proximo; }No; // procedimento para inserir no início void inserir_no_inicio(No **lista, int num){ No *novo = malloc(sizeof(No)); if(novo){ novo->valor = num; novo->proximo = *lista; *lista = novo; } else printf("Erro ao alocar memoria!\n"); } // procedimento para inserir no fim void inserir_no_fim(No **lista, int num){ No *aux, *novo = malloc(sizeof(No)); if(novo){ novo->valor = num; novo->proximo = NULL; // é o primeiro? if(*lista == NULL) *lista = novo; else{ aux = *lista; while(aux->proximo) aux = aux->proximo; aux->proximo = novo; } } else printf("Erro ao alocar memoria!\n"); } // procedimento para inserir no meio void inserir_no_meio(No **lista, int num, int ant){ No *aux, *novo = malloc(sizeof(No)); if(novo){ novo->valor = num; // é o primeiro? if(*lista == NULL){ novo->proximo = NULL; *lista = novo; } else{ aux = *lista; while(aux->valor != ant && aux->proximo) aux = aux->proximo; novo->proximo = aux->proximo; aux->proximo = novo; } } else printf("Erro ao alocar memoria!\n"); } void inserir_ordenado(No **lista, int num){ No *aux, *novo = malloc(sizeof(No)); if(novo){ novo->valor = num; // a lista está vazia? if(*lista == NULL){ novo->proximo = NULL; *lista = novo; } // é o menor? else if(novo->valor < (*lista)->valor){ novo->proximo = *lista; *lista = novo; } else{ aux = *lista; while(aux->proximo && novo->valor > aux->proximo->valor) aux = aux->proximo; novo->proximo = aux->proximo; aux->proximo = novo; } } else printf("Erro ao alocar memoria!\n"); } No* remover(No **lista, int num){ No *aux, *remover = NULL; if(*lista){ if((*lista)->valor == num){ remover = *lista; *lista = remover->proximo; } else{ aux = *lista; while(aux->proximo && aux->proximo->valor != num) aux = aux->proximo; if(aux->proximo){ remover = aux->proximo; aux->proximo = remover->proximo; } } } return remover; } No* buscar(No **lista, int num){ No *aux, *no = NULL; aux = *lista; while(aux && aux->valor != num) aux = aux->proximo; if(aux) no = aux; return no; } void imprimir(No *no){ printf("\n\tLista: "); while(no){ printf("%d ", no->valor); no = no->proximo; } printf("\n\n"); } int main(){ int opcao, valor, anterior; No *removido, *lista = NULL; do{ printf("\n\t0 - Sair\n\t1 - InserirI\n\t2 - inserirF\n\t3 - InserirM\n\t4 - InserirO\n\t5 - Remover\n\t6 - Imprimir\n\t7 - Buscar\n"); scanf("%d", &opcao); switch(opcao){ case 1: printf("Digite um valor: "); scanf("%d", &valor); inserir_no_inicio(&lista, valor); break; case 2: printf("Digite um valor: "); scanf("%d", &valor); inserir_no_fim(&lista, valor); break; case 3: printf("Digite um valor e o valor de referencia: "); scanf("%d%d", &valor, &anterior); inserir_no_meio(&lista, valor, anterior); break; case 4: printf("Digite um valor: "); scanf("%d", &valor); inserir_ordenado(&lista, valor); break; case 5: printf("Digite um valor a ser removido: "); scanf("%d", &valor); removido = remover(&lista, valor); if(removido){ printf("Elemento a ser removido: %d\n", removido->valor); free(removido); } else printf("Elemento inexistente!\n"); break; case 6: imprimir(lista); break; case 7: printf("Digite um valor a ser buscado: "); scanf("%d", &valor); removido = buscar(&lista, valor); if(removido) printf("Elemento encontrado: %d\n", removido->valor); else printf("Elemento nao encontrado!\n"); break; default: if(opcao != 0) printf("Opcao invalida!\n"); } }while(opcao != 0); return 0; }