二叉树删除

时间:2015-01-14 07:40:01

标签: c tree

给定:deleteTree()函数删除树,但不会将root更改为NULL,如果deleteTree()的用户没有将root更改为NULL并尝试使用root指针访问值,则可能会导致问题。我们可以修改deleteTree()函数来引用根节点,这样就不会发生这个问题。

[链接] http://www.geeksforgeeks.org/write-a-c-program-to-delete-a-tree/

怀疑:在deleteTree函数中,传递了main节点的副本,然后如何在deleteTree()中释放所有这些节点的实际内存。据说树被删除但是要删除的树不应该传递地址。此外,如果我们认为树实际上已被删除,那么根节点也会被删除,那么为什么它不会在主节点中变为NULL?

void deleteTree(struct node* node) 
{
  if (node == NULL) return;
  deleteTree(node->left);
  deleteTree(node->right);
  printf("\n Deleting node: %d", node->data);
  free(node);
}
int main()
{
  struct node *root = newNode(1); 
  root->left            = newNode(2);
  root->right          = newNode(3);
  root->left->left     = newNode(4);
  root->left->right   = newNode(5); 

  deleteTree(root);  
  root = NULL;

  printf("\n Tree deleted ");

  getchar();
  return 0;
}

修改后的代码:

void _deleteTree(struct node* node)
{
  if (node == NULL) return;

  _deleteTree(node->left);
  _deleteTree(node->right);
  printf("\n Deleting node: %d", node->data);
  free(node);
}


void deleteTree(struct node** node_ref)
{
  _deleteTree(*node_ref);
  *node_ref = NULL;
}

int main()
{
  struct node *root = newNode(1);
  root->left            = newNode(2);
  root->right          = newNode(3);
  root->left->left     = newNode(4);
  root->left->right   = newNode(5);


  deleteTree(&root);
  printf("\n Tree deleted ");

  getchar();
  return 0;
}

如果我们在main中而不是在deleteTree函数中设置root = NULL,那么在这种情况下如何释放呢?

2 个答案:

答案 0 :(得分:0)

你混淆了两个概念 - 内存释放,并将指针设置为NULL。通过使用free释放内存,指针现在指向未分配的内存。通过将节点*设置为NULL,您指示指针无效 - 您可以看到代码检查了该指针 - if (node == NULL ) return;。如果只是将root设置为NULL,则会产生内存泄漏,因为指向的内存仍然是已分配的。

此外 - It is said the tree is deleted but for the tree to be deleted shouldn't we pass the address - 您正在传递地址 - deleteTree(&root); - root是包含根节点地址的节点*。

希望这有帮助。

答案 1 :(得分:0)

在第一个代码中,函数void deleteTree(struct node* node)调用自身(递归)来释放每个节点的内存。It is said the tree is deleted but for the tree to be deleted shouldn't we pass the address,实际上para node是一个节点的地址,它是一个指针(struct node *)。当你拨打free(node)时,释放node指向的内存,而不是节点本身。

至于将root设置为NULL,第二个代码与逻辑上的第一个代码相同。如果函数void deleteTree(struct node** node_ref)是内联的,那么在编译之后,它将与您的第一个代码相同。