代码之家  ›  专栏  ›  技术社区  ›  Indranath Ghosh

我想将数据推送到二叉树中,但在3个输入后,它显示出分段错误

  •  0
  • Indranath Ghosh  · 技术社区  · 5 年前

    这是一个将数据输入二叉树的推送函数。它导致第三次呼叫出现分段错误。查看代码以了解更多信息。

    void push(){
      int data;
      printf("enter the data you want to enter");
      scanf("%d",&data);
      struct bst* temp;
      temp=(struct bst*)malloc(sizeof(struct bst*));
      temp->data=data;
      if(root==NULL){
        temp->right=NULL;
        temp->left=NULL;
        root=temp;
      }else{
        struct bst* p;
        p=root;
        while(p->left!=NULL || p->right!=NULL){
          if(data<<p->data){
             p=p->left;
           }else{
             p=p->right;
           }
        }
        if(data>>p->data){
          temp->left=NULL;
          temp->right=NULL;
          p->right=temp;
        }else{
          temp->left=NULL;
          temp->right=NULL;
          p->left=temp;
        }
      }
    }
    
    1 回复  |  直到 5 年前
        1
  •  1
  •   hhuseyin    5 年前

    当你遍历树时,你正在使用 p->left!= NULL OR p->right!= NULL 条件。在这种情况下,如果树的左侧不为NULL,则将NULL分配给p。然后将数据与NULL变量数据进行比较。这会导致分段错误。您需要在while条件中添加AND语句而不是OR:

    while(p->left!=NULL && p->right!=NULL){

    同样在这条线上 if(data>>p->data){ 您使用的是右移运算符,而不是更大的运算符。你应该正确地输入它。

        2
  •  1
  •   John Bollinger    5 年前

    所提供的代码存在许多问题,其中一些问题已在注释和另一个答案中给出。其中包括

    • 您没有为每个节点(每个@EddInglis)分配足够的空间。因此,当您设置一个或多个分配对象的成员时,您会在分配对象的边界之外写入,从而产生未定义的行为。 这可能是分段故障的来源 .作为一个相关但次要的问题,在C中,您不需要显式转换类型的值 void * 对于其他对象指针类型进行赋值,出于风格和良好的编程实践,您不应该这样做。

    • 遍历树的条件逻辑不正确(根据@hhusein)。条件 p->left!=NULL || p->right!=NULL 适用于所有不是叶子的节点,但您还需要适应只有一个子节点的内部节点的情况。这可能 不是 然而,segfault的原因。它很容易丢失数据和泄漏内存。

    • 你选择在树中移动哪个方向的条件逻辑是不正确的:

         if(data<<p->data){
      

      ...

       if(data>>p->data){
      

      这个 << >> 运算符计算按位左移和右移。您正在寻找关系运算符( < > ). 这不对你的segfault负责,但它会导致生成的二叉树无法成为二进制树 搜索 树。在大多数情况下,节点的排列会不正确。

        3
  •  0
  •   TruthSeeker    5 年前

    你的代码中有三个拼写错误,

    1. 你的 malloc 正在分配指针的大小而不是节点的大小。即malloc(sizeof(结构体bst))
    2. if(data<<p->data) 是左移数据而不是比较。替换为仅比较 if(data < p->data)
    3. if(data>>p->data) 是右移操作员,你需要 if(data>p->data)

    除了拼写错误外,还必须修复为新创建的节点找到正确占位符的逻辑。

    temp->left= NULL;
    temp->right= NULL;
    while(p){
        if(data < p->data){
           if(!p->left) {
               p->left = temp; 
               break;
               }
             p=p->left;
        }else if(data > p->data) { 
           if(!p->right) {
               p->right = temp; 
               break;
               }
           p=p->right; 
        }else{
           //Skip insertion for same key
           break;
        }
    }