Jump to content
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

jett

Inserção em Arvore Binária

Recommended Posts

jett

Bom, estou fazendo um programa em C que cadastra veículos utilizando a inserção por recursão em uma árvore binária. Quando vou cadastrar, insere o primeiro elemento, se eu tentar inserir o mesmo elemento outra vez, ele imprime uma mensagem dizendo que o veículo já foi cadastrado. Mas quando vou inserir um veículo com ID diferente, o programa dá pau e fecha. Não sei onde estou errando, por favor me ajudem. Segue abaixo o código temporário do meu programa:

#include <stdio.h>
typedef struct arvore{
   int id;
   char marca[50];
   char modelo[50];
   char cor[20];
   char proprietario[50];
   struct arvore *dir;
   struct arvore *esq;
}arvore;
arvore *aloca(arvore *novo){
   novo = (arvore*)calloc(1,sizeof(arvore));
   printf("Entre com a Identificacao do veiculo: ");
   scanf("%d", &(novo->id));
   printf("Digite a marca do veiculo: ");
   scanf("%s", &(novo->marca));
   printf("Digite o modelo do veiculo: ");
   scanf("%s", &(novo->modelo));
   printf("Digite a cor do veiculo: ");
   scanf("%s", &(novo->cor));
   printf("Digite o nome do proprietario do veiculo: ");
   scanf("%s", &(novo->proprietario));
   return novo;
}
void cadastrar(arvore **T, arvore *novo){
   if((*T) == NULL){
           novo->dir = NULL;
           novo->esq = NULL;
           (*T) = novo;
   }
   else{
           if(novo->id == (*T)->id){
               printf("\nVeiculo ja cadastrado!\n");
   }
   else if(novo->id < (*T)->id){
           cadastrar((*T)->esq, novo);
   }
   else{
           cadastrar((*T)->dir, novo);
   }
   }
   }


int main()
{
   int op;
   arvore *T = NULL;
   int id;
           printf("\n1 -Cadastrar novo veiculo: \n2 -Modificar dados de um veiculo \n3 -Buscar veiculo \n4 -Remover veiculo \n5 -Imprimir lista de veiculos\n6 -Imprimir arvore\n7 -Sair\n\n");
       scanf("%d",&op);
       while(op != 7)
   {
       if(op == 1){
           arvore *novo = aloca(novo);
           cadastrar(&T, novo);
       }
       if (op == 2){
           printf("\nDigite a identificacao do veiculo que deseja modificar:\n");
           scanf("%d",& id);
       }
       if (op == 3){
           printf("\nDigite a identificacao do veiculo que deseja buscar:\n");
           scanf("%d",& id);
         //  busca(T,id);
       }
       if (op == 4){
           printf("\nDigite a identificacao do veiculo que deseja remover:\n\n");
           scanf("%d",& id);
          // remover(&T,id);
       }
       if (op == 5){
           printf("\nLista dos veiculos: \n");
           printf("------------------------------------------------------------\n");
          // imprime(T);
       }
       if (op == 6){
           printf("\nArvore impressa: \n");
           printf("------------------------------------------------------------\n");
          // imprime_arvore(T);
       }
       printf("\n1 -Cadastrar novo veiculo: \n2 -Modificar dados de um veiculo \n3 -Buscar veiculo \n4 -Remover veiculo \n5 -Imprimir lista de veiculos\n6 -Imprimir arvore\n7 -Sair\n\n");
       scanf("%d",&op);
       }
   }

Edited by pmg
Falta LP no GeSHi
  • Vote 1

Share this post


Link to post
Share on other sites
pmg

Liga o máximo de warnings do teu compilador, e não aceitas compilações com warnings.

void cadastrar(arvore **T, arvore *novo){
   /* ... */
   else if(novo->id < (*T)->id){
           cadastrar((*T)->esq, novo);
   /* ... */

Tu chamas a funcao cadastrar() recursivamente -- não há nada de mal nisso.

Na primeira chamada (de dentro da main) chamas com os tipos correctos, nas chamadas seguintes (as chamadas recursivas) os tipos não batem certo: a funcao pretende um ponteiro para um ponteiro para arvore (arvore **T) mas tu passas um ponteiro para arvore ((*T)->esq).

Os warnings devem-te avisar disso!

Edited by pmg

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
jett

Então o correto seria o seguinte?

void cadastrar(arvore **T, arvore *novo){
   /* ... */
   else if(novo->id < (*T)->id){
           cadastrar(&(T)->esq, novo);
   /* ... */

Edited by pmg
Falta LP no GeSHi

Share this post


Link to post
Share on other sites
pmg

Nem por isso, não. Falta-te "desreferenciar" T:

cadastrar(&((*T)->esq), novo);

Mais uma coisa: para que é que serve o parametro da tua função aloca()? E o valor devolvido pela mesma função?


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
jett

Deu certo, muito obrigada!

Bom, usei o parâmetro da função aloca() para passar a variável 'novo' que chamo na main na hora de cadastrar, depois retorno o valor para a variável que a chamou, e assim passo o nó já alocado para a função cadastrar():

int main(){
/*...*/
if(op == 1){
           arvore *novo = aloca(novo);
           cadastrar(&T, novo);
       }
/*... */

Edited by brunoais
geshi

Share this post


Link to post
Share on other sites
pmg

Entao e se chamasses a função com outra variavel qualquer (do tipo correcto)? fazia diferença?

arvore *novo;
arvore *velho;
arvore *outra;
novo = aloca(novo);
novo = aloca(velho);
novo = aloca(outra);

Não achas mais cómodo definir a função sem parametros e chamá-la sem argumentos?

arvore *aloca(void) {
   arvore *novo;
   /* ... */
   return novo;
}

arvore *novo;
novo = aloca();


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
jett

Verdade. Então na função aloca ficaria:

arvore *aloca(void) {
  arvore *novo = (arvore*)malloc(sizeof(arvore));
   /* ... */
   return novo;
}

Certo?

Share this post


Link to post
Share on other sites
HappyHippyHippo

Verdade. Então na função aloca ficaria:

arvore *aloca(void) {
  arvore *novo = (arvore*)malloc(sizeof(arvore));
   /* ... */
   return novo;
}

Certo?

sim

na realidade não necessitas de fazer o cast do retorno do malloc, basta:

arvore * aloca(void)
{
  return memset(malloc(sizeof(arvore)), 0, sizeof(arvore));
}

ps : nota que não estou a fazer as verificações do resultado das chamadas das funções malloc e/ou memset que deverias fazer ...

Edited by HappyHippyHippo

IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
pmg

Correcto!

novo = aloca(novo);

Quando eu vi o novo a ser usado nos dois lados do =, fiquei logo alerta!

Depois ao ver a implementacao da funcao vi que eram coisas a mais: ou usas o valor de retorno (como eu sugeri) ou usas o parametro (*).

// (*) usando o parametro
void aloca(arvore **novo);


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
feitosar
Em 03/14/2013 às 11:32, pmg disse:

Correcto!

 


novo = aloca(novo);
 

 

Quando eu vi o novo a ser usado nos dois lados do =, fiquei logo alerta!

Depois ao ver a implementacao da funcao vi que eram coisas a mais: ou usas o valor de retorno (como eu sugeri) ou usas o parametro (*).

 


// (*) usando o parametro
void aloca(arvore **novo);
 

 

Boa noite , você tem esse código completo? Rodando e imprimindo?

Share this post


Link to post
Share on other sites
HappyHippyHippo

o código de gestão de uma árvore binária é simples de criar, no entanto, duvido que alguem o te dè de bandeja

a maneira como te apresentas aqui no fórum parece que procuras algo como o freelancing.com


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.