【问题标题】:(Binary tree) Code doesn't work but returns no error when compiling(二叉树)代码不起作用但编译时不返回错误
【发布时间】:2020-10-10 19:17:31
【问题描述】:

编译此代码时,编译器不会返回任何警告或错误,但代码根本不起作用。

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

     }
}

【问题讨论】:

    标签: c pointers binary-tree


    【解决方案1】:

    (1) 实际上你应该收到 SEG Fault 因为你还没有将 arovore1 初始化为 NULL。

    (2) 这里要提到的重要一点是,我们使用双指针来摆脱返回值。而你在这里所做的有点矛盾。

    --> 基本上我们将创建一个节点(arvore1),然后发送节点的地址(&arvore1) 到 insertNode (inserirDado) 函数,并在其中更新相应的节点 地址到新创建的节点(临时)。 我在这里附上了工作代码。请参考此内容,如有任何疑问,您可以发表评论。

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

    【讨论】:

      【解决方案2】:

      如果您使用 GCC 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 指向的地方,而不是初始化it

      另请阅读:

      Why should I always enable compiler warnings?

      【讨论】:

      • 会这样做。你说的和其他人匹配,还是不行。不返回错误,只是一个警告:控制到达非空函数 [-Wreturn-type] 的结尾。
      • @TheKenjiMT:可能还有其他问题。我只关注这个特定的错误。请注意,您可能会问另一个问题 - 但请花时间仔细检查您的代码以及编译器警告您的非空函数。
      【解决方案3】:

      您必须先分配缓冲区并将其分配给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);
      
      }
      

      【讨论】:

      • 两种解决方案都试过了,都不行。我只收到一个警告:控制到达非空函数 [-Wreturn-type] 的结尾。
      • @TheKenjiMT 代码seems working。你能指望什么?另外请确保您正在编译和运行最新的预期代码。
      • 将“struct node”改为“typedef struct node”并初始化为NULL后,就可以正常工作了。我不知道为什么,因为我不知道添加 typedef 是否有区别。感谢您的帮助。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-09
      • 1970-01-01
      • 1970-01-01
      • 2021-03-25
      • 2013-04-14
      • 1970-01-01
      相关资源
      最近更新 更多