Ir para o conteúdo
jett

Inserção em Arvore Binária

Mensagens Recomendadas

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);
       }
   }

Editado por pmg
Falta LP no GeSHi
  • Voto 1

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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!

Editado por 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!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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);
   /* ... */

Editado por pmg
Falta LP no GeSHi

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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);
       }
/*... */

Editado por brunoais
geshi

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
jett

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

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

Certo?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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 ...

Editado por HappyHippyHippo

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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.