【问题标题】:root = NULL not working in my C programroot = NULL 在我的 C 程序中不起作用
【发布时间】:2017-10-25 17:28:24
【问题描述】:

我创建了以下函数来从树中删除节点:

void delNode(int key, Node *root) {
  if(root->data != key && root->left != NULL) {
    delNode(key,root->left);
  }
  if(root->data != key && root->right != NULL) {
    delNode(key,root->right);
  }
  if(root->data != key && root->left == NULL) {
    return;
  }
  if(root->data != key && root->right == NULL) {
    return;
  }
  if(root->data == key) {
    root = NULL;
    return;
  }
}

我有以下遍历功能

void printInorder(Node *root) {
  if(root!=NULL) {
    printInorder(root->left);
    printf("%d ",root->data);
    printInorder(root->right);
  }
}

当我删除一个元素并显示树时,甚至会显示已删除的节点。

PS:我想删除整个树,保持节点为根

【问题讨论】:

  • 向我们展示根有哪些元素(节点,向我们展示节点,您在其中创建该结构和所有元素)。
  • 编译所有警告和调试信息:gcc -Wall -Wextra -gGCC使用调试器 gdb(和valgrind)。您的 fix-my-code 问题在这里是题外话。
  • root 是指向树中节点的指针。如果您将 NULL 分配给 root,这并不意味着该节点已被删除,但它只是破坏了 root 指针和它指向的节点的链接,但父级 leftright 指针仍然指向那个节点。您需要free (root) 才能删除它。但是仅仅释放它是不够的,您需要断开父节点和已释放节点之间的链接(通过将 NULL 分配给各自的 leftright 指针)。您的delNode() 函数不完整。
  • free(root) 删除根指向的位置的存在。我希望它存在,只是它必须为 NULL

标签: c data-structures recursive-datastructures


【解决方案1】:

这不会删除节点,root 只是对内存位置的引用。
这里有一个简单的解释:
所以root 就像一个指向盒子的箭头,你将箭头指向某个盒子(内存位置),比如 box1 和一些内容。 root = NULL 在这里,您将箭头指向任何东西,即空的空间,但 box1 中仍然有内容。

你需要做的是,清除box1的内容

free(root);   //This is make memory space available, i.e deallocates the memory 

您删除树节点的逻辑也有缺陷/不完整(可能不完整),但我相信您已经知道了。

【讨论】:

  • free(root) 删除根指向的位置的存在。
  • 我希望它存在,只是它必须为 NULL
  • @PrajvalM 节点必须存在并且为 NULL 是没有意义的,你在自相矛盾。
  • 如果 root == NULL 打印出来时我不会打印它
  • 喜欢使用 nullptr
【解决方案2】:

您的delNode 方法不正确。从树中删除一个节点并不是那么简单。只需考虑如何处理要删除的节点的左子树和右子树。通过分配root= NULL;,您将一事无成。通过使用 free(root) ,除了永久删除当前指向的 root 的子节点(子树)之外,您不会实现任何目标。我已经更正了您的方法,请参见下文并尝试以下方法:-

    Node* delNode(int key, Node *root) {
      Node *nodeToBeDeleted=NULL
      Node *predecessor = root;
      if(root->data != key && root->left != NULL) {
        nodeToBeDeleted = delNode(key,root->left);
        if(nodeToBeDeleted){  //if we found the node to be deleted in left sub tree
          if(nodeToBeDeleted->right != NULL){
             root->left = nodeToBeDeleted->right;
             predecessor = findPredecessor(root->right);
             predecessor->left = nodeToBeDeleted->left;
          }          
          else{
             root->left = nodeToBeDeleted->left;
          }
          free(nodeToBeDeleted);
        }
      }
      if(root->data != key && root->right != NULL) {
        nodeToBeDeleted = delNode(key,root->right);
         if(nodeToBeDeleted){  //if we found the node to be deleted in the right sub tree
            if(nodeToBeDeleted->right != NULL){
             root->right = nodeToBeDeleted->right;
             predecessor = findPredecessor(root->right);
             predecessor->left = nodeToBeDeleted->left;
          }          
          else{
             root->right = nodeToBeDeleted->left;
          }
          free(nodeToBeDeleted);
         }
      }
      if(root->data != key && root->left == NULL) {
        return NULL;
      }
      if(root->data != key && root->right == NULL) {
        return NULL;
      }
      if(root->data == key) {
        return root;
      }

    }

添加以下方法来查找树的前驱节点

    Node* findPredecessor(Node *root) {
     Node *predecessor = root;
      if(root!=NULL) {
        predecessor = findPredecessor(root->left);   
      }
      if(predecessor == NULL)
            return root;
      else
            return predecessor;
    }

【讨论】:

    【解决方案3】:

    我需要先释放节点,然后使用删除。我的错。

    【讨论】:

      猜你喜欢
      • 2022-01-11
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多