简体   繁体   English

二叉树删除

[英]Binary Tree Deletion

Given: The deleteTree() function deletes the tree, but doesn't change root to NULL which may cause problems if the user of deleteTree() doesn't change root to NULL and tries to access values using root pointer. 给定:deleteTree()函数删除树,但不会将root更改为NULL,如果deleteTree()的用户未将root更改为NULL并尝试使用根指针访问值,则可能导致问题。 We can modify the deleteTree() function to take reference to the root node so that this problem doesn't occur. 我们可以修改deleteTree()函数以引用根节点,以便不会发生此问题。

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

Doubt: In the deleteTree function the copy of the node from the main is passed then how are the actual memory of all these nodes freed in the deleteTree(). 疑问:在deleteTree函数中,将传递主节点的副本,然后如何在deleteTree()中释放所有这些节点的实际内存。 It is said the tree is deleted but for the tree to be deleted shouldn't we pass the address. 据说树被删除了,但要删除的树不应该通过地址。 Also if we consider that the tree is actually deleted then along with it the root node is also deleted so why doesn't it change to NULL in the main? 另外,如果我们认为树实际上已被删除,那么根节点也会随之被删除,那么为什么树的主节点不更改为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;
}

The modified code: 修改后的代码:

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

How does the freeing happen in this case what if we set the root=NULL in main and not in the deleteTree function? 在这种情况下,如果我们在main中而不是在deleteTree函数中设置root = NULL,释放将如何发生?

You are confusing two concepts - memory freeing, and setting the pointer to NULL . 您将混淆两个概念-释放内存和将指针设置为NULL By using free the memory is freed and th pointer now points to an unallocated piece of memory. 通过使用free ,可以释放内存,并且指针现在指向未分配的内存。 By setting the node* to NULL, you are indicating that the pointer is not valid - you can see that the code checks for that - if (node == NULL ) return; 通过将node *设置为NULL,表示指针无效-您可以看到代码检查了该内容- if (node == NULL ) return; . If you just set the root to NULL you are creating a memory leak, since the memory pointed to remains allocated. 如果仅将根设置为NULL,则将创建内存泄漏,因为指向的内存仍处于分配状态。

Also - It is said the tree is deleted but for the tree to be deleted shouldn't we pass the address - you are passing the address - deleteTree(&root); 另外- It is said the tree is deleted but for the tree to be deleted shouldn't we pass the address -您正在传递地址deleteTree(&root); - root is a node* containing the address of the root node. -root是一个节点*,其中包含根节点的地址。

Hope this helps. 希望这可以帮助。

In the first code, function void deleteTree(struct node* node) calls itself(recursion) to free the memory of each node. 在第一个代码中,函数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 , in fact the para node is a address of one node, it is a pointer( struct node * ). It is said the tree is deleted but for the tree to be deleted shouldn't we pass the address ,实际上,para node是一个node的地址,它是一个指针( struct node * )。 When you call free(node) , you free the memory which the node points to, not the node itself. 调用free(node) ,将释放node指向的内存,而不是节点本身。

As for set root to NULL , the second code is same with your first code logically. 至于将root设置为NULL ,第二个代码在逻辑上与第一个代码相同。 If the function void deleteTree(struct node** node_ref) is inline, then after compiling, it will be same with your first code. 如果函数void deleteTree(struct node** node_ref)是内联函数,则在编译后,它将与您的第一个代码相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM