6
I have several doubts about the operation of binary tree in C.
I have a code for insertion, removal and printing in order, pre-order and post-order. These codes were taken from the Internet, because I couldn’t understand what each line does by following my teacher’s explanations.
Struct
struct No{
int numero;
struct No *esquerda;
struct No *direita;
};
typedef struct No No;
1st Doubt
In this case I created a struct No
and created 2 pointers of the type No being left and right, correct?
Creation of the Tree
void criarArvore(No **pRaiz){
*pRaiz = NULL;
}
2nd doubt
In this code I created the tree, but what it means **pRaiz
?
Third doubt
If you have someone with time, you can tell me what is happening on each line of code insertion below?
4th doubt
If you have someone with time, can you tell me what is happening in each line of code removal below?
Insertion
void inserir(No **pRaiz, int numero){
if(*pRaiz == NULL){
*pRaiz = (No *) malloc(sizeof(No));
(*pRaiz)->esquerda = NULL;
(*pRaiz)->direita = NULL;
(*pRaiz)->numero = numero;
}else{
if(numero < (*pRaiz)->numero)
inserir(&(*pRaiz)->esquerda, numero);
if(numero > (*pRaiz)->numero)
inserir(&(*pRaiz)->direita, numero);
}
}
Removal
No *MaiorDireita(No **no){
if((*no)->direita != NULL)
return MaiorDireita(&(*no)->direita);
else{
No *aux = *no;
if((*no)->esquerda != NULL) // se nao houver essa verificacao, esse nó vai perder todos os seus filhos da esquerda!
*no = (*no)->esquerda;
else
*no = NULL;
return aux;
}
}
No *MenorEsquerda(No **no){
if((*no)->esquerda != NULL)
return MenorEsquerda(&(*no)->esquerda);
else{
No *aux = *no;
if((*no)->direita != NULL) // se nao houver essa verificacao, esse nó vai perder todos os seus filhos da direita!
*no = (*no)->direita;
else
*no = NULL;
return aux;
}
}
void remover(No **pRaiz, int numero){
if(*pRaiz == NULL){ // esta verificacao serve para caso o numero nao exista na arvore.
printf("Numero nao existe na arvore!");
getch();
return;
}
if(numero < (*pRaiz)->numero)
remover(&(*pRaiz)->esquerda, numero);
else
if(numero > (*pRaiz)->numero)
remover(&(*pRaiz)->direita, numero);
else{ // se nao eh menor nem maior, logo, eh o numero que estou procurando! :)
No *pAux = *pRaiz; // quem programar no Embarcadero vai ter que declarar o pAux no inicio do void! :[
if (((*pRaiz)->esquerda == NULL) && ((*pRaiz)->direita == NULL)){ // se nao houver filhos...
free(pAux);
(*pRaiz) = NULL;
}
else{ // so tem o filho da direita
if ((*pRaiz)->esquerda == NULL){
(*pRaiz) = (*pRaiz)->direita;
pAux->direita = NULL;
free(pAux); pAux = NULL;
}
else{ //so tem filho da esquerda
if ((*pRaiz)->direita == NULL){
(*pRaiz) = (*pRaiz)->esquerda;
pAux->esquerda = NULL;
free(pAux); pAux = NULL;
}
else{ //Escolhi fazer o maior filho direito da subarvore esquerda.
pAux = MaiorDireita(&(*pRaiz)->esquerda); //se vc quiser usar o Menor da esquerda, so o que mudaria seria isso:
pAux->esquerda = (*pRaiz)->esquerda; // pAux = MenorEsquerda(&(*pRaiz)->direita);
pAux->direita = (*pRaiz)->direita;
(*pRaiz)->esquerda = (*pRaiz)->direita = NULL;
free((*pRaiz)); *pRaiz = pAux; pAux = NULL;
}
}
}
}
}
Printing in Order
void exibirEmOrdem(No *pRaiz){
if(pRaiz != NULL){
exibirEmOrdem(pRaiz->esquerda);
printf("\n%i", pRaiz->numero);
exibirEmOrdem(pRaiz->direita);
}
}
Pre-order Printing
void exibirPreOrdem(No *pRaiz){
if(pRaiz != NULL){
printf("\n%i", pRaiz->numero);
exibirPreOrdem(pRaiz->esquerda);
exibirPreOrdem(pRaiz->direita);
}
}
Post-order Printing
void exibirPosOrdem(No *pRaiz){
if(pRaiz != NULL){
exibirPosOrdem(pRaiz->esquerda);
exibirPosOrdem(pRaiz->direita);
printf("\n%i", pRaiz->numero);
}
}
thanks for the help. You could supplement the reply by commenting on the removal too, I have doubts on this part.
– Wendell
Okay, I finished making the answer. Any doubt, say there that we try to heal.
– Henrique Santiago