Dando continuidade ao nosso Curso de Programação C, vamos aprender nesta aula como buscar um elemento em uma ÁRVORE BINÁRIA DE BUSCA de forma recursiva.
Uma busca recursiva em uma árvore binária é bem intuitiva, uma vez que os passos lógicos são bem previsíveis.
Como recebemos a raiz da árvore, a primeira ação é verificar se essa raiz não é nula. Se for, já podemos retornar null, indicando que o elemento procurado não foi encontrado.
Contudo, se a raiz não for nula, o segundo passo é verificar se é o elemento procurado. Se for, retornamos a raiz (endereço do nó que possui o elemento procurado).
Porém, se não for o elemento procurado, o terceiro passo é fazer uma chamada recursiva para a esquerda, se o elemento procurado for menor que a raiz, ou para a direita caso contrário.
Não esqueça que nossa função retorna algo, então esse retorno precisa ser propagado em cada chamada recursiva, senão será perdido e não saberemos qual foi o resultado da busca.
/* Função recursiva para buscar um elemento em uma árvore binária de busca */ NoArv* buscar_versao_1(NoArv *raiz, int num){ if(raiz){ if(num == raiz->valor) return raiz; else if(num < raiz->valor) return buscar_versao_1(raiz->esquerda, num); else return buscar_versao_1(raiz->direita, num); } return NULL; }
Código completo de exemplo em C para uma Árvore Binária de Busca
/* Aula 269: Como BUSCAR em uma Árvore Binária de Busca? VERSÃO RECURSIVA Código escrito por Wagner Gaspar Setembro de 2021 */ typedef struct no{ int valor; struct no *direita, *esquerda; }NoArv; NoArv* inserir_versao_1(NoArv *raiz, int num){ if(raiz == NULL){ NoArv *aux = malloc(sizeof(NoArv)); aux->valor = num; aux->esquerda = NULL; aux->direita = NULL; return aux; } else{ if(num < raiz->valor) raiz->esquerda = inserir_versao_1(raiz->esquerda, num); else raiz->direita = inserir_versao_1(raiz->direita, num); return raiz; } } void inserir_versao_2(NoArv **raiz, int num){ if(*raiz == NULL){ *raiz = malloc(sizeof(NoArv)); (*raiz)->valor = num; (*raiz)->esquerda = NULL; (*raiz)->direita = NULL; } else{ if(num < (*raiz)->valor) inserir_versao_2(&((*raiz)->esquerda), num); else inserir_versao_2(&((*raiz)->direita), num); } } void inserir_versao_3(NoArv **raiz, int num){ NoArv *aux = *raiz; while(aux){ if(num < aux->valor) raiz = &aux->esquerda; else raiz = &aux->direita; aux = *raiz; } aux = malloc(sizeof(NoArv)); aux->valor = num; aux->esquerda = NULL; aux->direita = NULL; *raiz = aux; } NoArv* buscar_versao_1(NoArv *raiz, int num){ if(raiz){ if(num == raiz->valor) return raiz; else if(num < raiz->valor) return buscar_versao_1(raiz->esquerda, num); else return buscar_versao_1(raiz->direita, num); } return NULL; } void imprimir_versao_1(NoArv *raiz){ // 50 25 30 100 if(raiz){ printf("%d ", raiz->valor); imprimir_versao_1(raiz->esquerda); imprimir_versao_1(raiz->direita); } } void imprimir_versao_2(NoArv *raiz){ // 25 30 50 100 if(raiz){ imprimir_versao_2(raiz->esquerda); printf("%d ", raiz->valor); imprimir_versao_2(raiz->direita); } } int main(){ NoArv *busca, *raiz = NULL; int opcao, valor; do{ printf("\n\t0 - Sair\n\t1 - Inserir\n\t2 - Imprimir\n\t3 - Buscar\n"); scanf("%d", &opcao); switch(opcao){ case 1: printf("\n\tDigite um valor: "); scanf("%d", &valor); //raiz = inserir_versao_1(raiz, valor); //inserir_versao_2(&raiz, valor); inserir_versao_3(&raiz, valor); break; case 2: printf("\n\tPrimeira impressao:\n\t"); imprimir_versao_1(raiz); printf("\n"); printf("\n\tSegunda impressao:\n\t"); imprimir_versao_2(raiz); printf("\n"); break; case 3: printf("\n\tDigite o valor a ser procurado: "); scanf("%d", &valor); busca = buscar_versao_1(raiz, valor); if(busca) printf("\n\tValor encontrado: %d\n", busca->valor); else printf("\n\tValor nao encontrado!\n"); break; default: if(opcao != 0) printf("\n\tOpcao invalida!!!\n"); } }while(opcao != 0); return 0; }