(Двоичное дерево) Код не работает, но при компиляции не возвращает ошибок - PullRequest
0 голосов
/ 20 июня 2020

При компиляции этого кода компилятор не возвращает никаких предупреждений или ошибок, но код просто не работает.

Функция InserirDado должна рекурсивно создавать узлы и сохранять значения на них, в node.valor, применяя условия, которые я установил ранее.

void inserirDado(struct node **no, int numero)
{
     if(*no == NULL) { //Se nao houver um nodo anterior, o primeiro numero se torna RAIZ.

          * no = (struct node *) malloc(sizeof(struct node));
          (*no)->direita = NULL;
          (*no)->esquerda = NULL;
          (*no)->valor = numero;

     }else{ //Caso contrario, a definicao do numero, se entrara no nodo esquerdo ou direito.
          if (numero < (*no)->valor) {
               inserirDado(&(*no)->esquerda, numero);
          }
          else
          {
               inserirDado(&(*no)->direita, numero);
          }
          
     }
}

В emOrdem , функции вызывают себя, пока не достигнут листьев, затем он должен распечатать значения хранится в node.valor:

void emOrdem(struct node *no)
    {
         if(no != NULL)
         {
              emOrdem(no->esquerda);
              printf("%i", no->valor);
              emOrdem(no->direita);
    
         }
    }

Полный код:

#include <stdio.h>
#include <stdlib.h>

struct node
{
     int valor;
     struct node *esquerda;
     struct node *direita;
};

void inserirDado(struct node **no, int numero);

void emOrdem(struct node *no);

int main(void) {

    struct node **arvore1;
    inserirDado(arvore1, 4);
    inserirDado(arvore1, 2);
    inserirDado(arvore1, 3);
    inserirDado(arvore1, 10);
    emOrdem(*arvore1);

}

//Funcao de colocar um numero aleatoria dentro de um Node.
//Ao fazer isso com varios numeros, serao criados nodos com descendentes.

void inserirDado(struct node **no, int numero)
{
     if(*no == NULL) { //Se nao houver um nodo anterior, o primeiro numero se torna RAIZ.

          * no = (struct node *) malloc(sizeof(struct node));
          (*no)->direita = NULL;
          (*no)->esquerda = NULL;
          (*no)->valor = numero;

     }else{ //Caso contrario, a definicao do numero, se entrara no nodo esquerdo ou direito.
          if (numero < (*no)->valor) {
               inserirDado(&(*no)->esquerda, numero);
          }
          else
          {
               inserirDado(&(*no)->direita, numero);
          }
          
     }
}

void emOrdem(struct node *no)
{
     if(no != NULL)
     {
          emOrdem(no->esquerda);
          printf("%i", no->valor);
          emOrdem(no->direita);

     }
}

Ответы [ 3 ]

1 голос
/ 20 июня 2020

Вы должны выделить буфер и назначить его arvore1 перед передачей его inserirDado.

int main(void) {

    struct node **arvore1 = malloc(sizeof(struct node*)); // add malloc()
    inserirDado(arvore1, 4);
    inserirDado(arvore1, 2);
    inserirDado(arvore1, 3);
    inserirDado(arvore1, 10);
    emOrdem(*arvore1);

}

Другой вариант - изменить arvore1 с «указателя на указатель» на «указатель» "и передайте указатель на него в inserirDado.

int main(void) {

    struct node *arvore1 = NULL;
    inserirDado(&arvore1, 4);
    inserirDado(&arvore1, 2);
    inserirDado(&arvore1, 3);
    inserirDado(&arvore1, 10);
    emOrdem(arvore1);

}
1 голос
/ 21 июня 2020

(1) На самом деле вы должны получить SEG Fault, потому что вы не инициализировали arovore1 значением NULL.

(2) Здесь важно упомянуть, что мы используем двойные указатели, чтобы избавиться от возвращаемых значений. И то, что вы здесь сделали, немного противоречит этому.

-> В основном мы создадим узел (arvore1), а затем отправим адрес узла (& arvore1) в функцию insertNode (insertirDado) и внутри этого мы обновляем соответствующий узел в этом адресе на вновь созданный узел (temp). Я прикрепил сюда рабочий код. Пожалуйста, обратитесь к этому и, в случае любых сомнений, вы можете их прокомментировать.

#include <stdio.h>
#include <stdlib.h>

struct node
{
     int valor;
     struct node *esquerda;
     struct node *direita;
};

void inserirDado(struct node **no, int numero);

void emOrdem(struct node *no);

int main(void) {

    struct node *arvore1 = NULL;
    inserirDado(&arvore1, 4);
    emOrdem(arvore1);

}

//Funcao de colocar um numero aleatoria dentro de um Node.
//Ao fazer isso com varios numeros, serao criados nodos com descendentes.

void inserirDado(struct node **no, int numero)
{
     if(*no == NULL) { //Se nao houver um nodo anterior, o primeiro numero se torna RAIZ.

          struct node *temp = (struct node *) malloc(sizeof(struct node));
          (temp)->direita = NULL;
          (temp)->esquerda = NULL;
          (temp)->valor = numero;
          *no = temp;

     }else{ //Caso contrario, a definicao do numero, se entrara no nodo esquerdo ou direito.
          if (numero < (*no)->valor) {
               inserirDado(&(*no)->esquerda, numero);
          }
          else
          {
               inserirDado(&(*no)->direita, numero);
          }
          
     }
}

void emOrdem(struct node *no)
{
     if(no != NULL)
     {
          emOrdem(no->esquerda);
          printf("%d", no->valor);
          emOrdem(no->direita);

     }
}
1 голос
/ 20 июня 2020

Если вы скомпилируете этот код с G CC 10, с переключателями -W -Wextra -Wall (что, кстати, не все предупреждения), вы получите:

<source>: In function 'main':
<source>:18:5: warning: 'arvore1' is used uninitialized in this function [-Wuninitialized]
   18 |     inserirDado(arvore1, 4);
      |     ^~~~~~~~~~~~~~~~~~~~~~~

GodBolt

, и это показывает вам, где проблема: вы пытаетесь инициализировать место arvore1 это указывает вместо инициализации его .

Также прочтите:

Почему я должен всегда включать предупреждения компилятора?

...