【问题标题】:removing leaves doesn't affect a BST - C去除叶子不会影响 BST - C
【发布时间】:2012-06-01 05:11:41
【问题描述】:

我编写了一个函数来使 BST 的所有叶子无效。 BST当然有一个左右指针和一个叫做data的char来存储节点的值。

void removeLeaves(struct Tree* T){
  if(T->left == NULL && T->right == NULL){
    printf("removing %c\n", T->data);
    T=NULL;
  }
  else{
    if(T->left!=NULL){
      removeLeaves(T->left);
    }
    if(T->right!=NULL){  
      removeLeaves(T->right);
    }
  }  
}

我在调用这个函数之前和之后打印树。 尽管上面的 print 语句有效并打印了无效的节点,但结果树是相同的。 我有类似的东西:

print(BST);
removeLeaves(BST);
print(BST);

知道发生了什么吗? 谢谢。

【问题讨论】:

    标签: c pointers struct binary-search-tree


    【解决方案1】:

    T=NULL; 将 null 分配给本地指针,而不是树中的任何内容。您需要使用struct Tree **,以便您可以修改struct Tree *

    void removeLeaves(struct Tree ** T){
      if((*T)->left == NULL && (*T)->right == NULL){
        printf("removing %c\n", (*T)->data);
        *T = NULL;
      }
      else{
        if((*T)->left!=NULL){
          pruneTree((*T)->left);
        }
        if((*T)->right!=NULL){  
          pruneTree((*T)->right);
        }
      }  
    }
    

    【讨论】:

    • 为什么是struct Tree ** T?为什么不只是*T = NULL 不起作用?我假设当我们有struct Tree* T 时,T 将是指向树的指针。所以我们只是取消引用它并将其设置为 null。
    • 感谢您的回复!我收到错误:从 removeLeaves((*T)->left) 中的不兼容指针类型传递“removeLeaves”的参数 1;
    • @MinaHany 你现在需要传入一个指向该元素的指针:removeLeaves(&(*T)->left);
    【解决方案2】:

    您是按值传递 T,因此将 T 设置为 null 不会执行任何操作(T 只是指针的本地副本)。

    您需要某种方式将 T 的“所有者”(即 parent->left 或 parent->right)设置为 null。

    (同样将 T 设置为 null 会导致内存泄漏 - 你需要 free() 吗?)

    【讨论】:

    • 我知道我在某个地方的指针有问题!非常感谢 :) 是的,我确实需要释放,但我暂时不考虑它。
    【解决方案3】:

    你有你需要的零件。主要是对它们进行重新排序。

    void removeLeaves(struct Tree* const T){
      if(T->left!=NULL){
        removeLeaves(T->left);
        T->left = NULL;
      }
      if(T->right!=NULL){  
        removeLeaves(T->right);
        T->right = NULL;
      }
    }
    

    但是请注意const。您的代码可以在没有它的情况下运行,但它不应该,因为设置 T = NULL 实际上并没有做任何事情,尽管可能会这样做。

    更新: @PaulP.R.O. 的回答很有趣,顺便说一句。我更喜欢我的,但你可以两个都试一下,看看哪个适合。

    顺便说一句,请确保您不需要在某处调用free(),以防止内存泄漏。

    【讨论】:

    • 实际上这会移除所有的叶子,最后只剩下根节点:) 是的,我必须 free() 但我现在把它排除在外。
    • 我误会了。我以为您只希望保留根节点。感谢您的更新。
    • 我读了我的问题,明白你为什么误解了。我的错,这非常具有误导性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-16
    • 1970-01-01
    • 2017-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多