简体   繁体   English

仅通过引用删除二叉树传递节点中的节点

[英]deletion of a node in binary tree passing node by reference only

I am trying to delete a binary tree, my program work as follows: 我试图删除一个二叉树,我的程序工作如下:

(1) It reads the number of nodes to be created in tree. (1)读取要在树中创建的节点数。

(2) It reads all those nodes. (2)读取所有这些节点。

(3) It print the tree formed by those nodes. (3)打印由那些节点形成的树。

(4) It reads the node to be delete at terminal. (4)在终端读取要删除的节点。

Until here everything works fine but when i try to delete the desired node then it gives segmentation fault error. 到这里为止一切正常,但是当我尝试删除所需的节点时,它会给出分段错误错误。

Note: I have to pass the root by reference only (thats why i have kept two pointers for root in delete_tree_node(int delete_val, node **root)). 注意:我必须仅通过引用传递根(这就是为什么我在delete_tree_node(int delete_val,node ** root)中保留了两个root指针)的原因。

My approach to do so is: I call recursively the function delete_tree_node() by left and right child in order to traverse the tree until i get the value of node equal to the value the node which user wants to delete.And once if i get that place then i free() that node. 我这样做的方法是:我通过左右子递归地调用函数delete_tree_node()以便遍历树直到我得到的node值等于用户想要删除的节点的值。那个地方然后我free()那个节点。

My code to achieve this is: (which gives segmentation problem): 我要实现此目的的代码是:(它给出了分段问题):

delete_tree_node(int delete_val, node  **root)//two "**" because i call by reference in function call    
{
 node*temp1;
 temp1=(*root);
if(delete_val==(*root)->freq)
   {    
     free((*root));    
     temp1=temp1->left;    
     (*root)=temp1;     
   }   

if(delete_val<temp1->freq)    
   { 
     delete_tree_node(delete_val,&temp1->left);    
   }
if(delete_val>temp1->freq)    
   {
     delete_tree_node(delete_val,&temp1->right);
   }    
}

It's function call is : 它的函数调用是:

delete_tree_node(delete_val, & head);//I give reference

Could some one help me in knowing : 有人可以帮助我了解一下吗:

(1) Why it gives segmentation error. (1)为什么会产生分割错误。

(2) Is my logic is correct to delete the desired node ?, If not then could you please give me a piece of code to make as reference? (2)我的逻辑删除所需的节点是否正确?,否则请您给我一段代码作为参考?

Why it gives segmentation fault? 为什么会产生细分错误?

Because you free the memory pointed by *root before you try to access the same memory in temp1->left . 因为在尝试以temp1->left访问相同的内存之前,您已经释放了*root指向的内存。

Let's look at things closely :- 让我们仔细看一看:-

temp1 = (*root)

temp1 now holds the same memory address as (*root), ie both are some numbers that point to the same address. temp1现在与(* root)拥有相同的内存地址,即,两者都是一些指向相同地址的数字。 For the sake of clarity, let's assume that number to be '6'. 为了清楚起见,我们假定该数字为“ 6”。 So, both of them point to the memory address '6'. 因此,它们两个都指向存储器地址“ 6”。 Note, they are not equal to the value at that address, but are just pointing to that. 注意,它们不等于该地址上的值,而只是指向该地址。

Now, free((*root)); 现在, free((*root)); tells the system that you are freeing the memory location pointed to by (*root), which in this case is 6. Once you free the memory, you lose access permission to that memory and next time you request it (through temp1->left ), you get the segmentation fault. 告诉系统您正在释放(* root)指向的内存位置,在这种情况下为6。释放内存后,您将失去对该内存的访问权限,并且下次请求该内存时(通过temp1->left ),则会出现细分错误。

I hope that clarifies what is causing the segmentation fault. 我希望可以弄清楚是什么原因造成了分段错误。

A cursory glance tells me that you could fix this by freeing (*root) at the end. 粗略地看一眼就告诉我,您可以通过在最后释放(* root)来解决此问题。 In fact, the recursive call would be clearer that way, since you can describe it through this pseudo-code :- 实际上,递归调用会更清晰,因为您可以通过以下伪代码来描述它:

delete left subtree
delete right subtree
delete root

I will not delve into the correctness of the logic as it appears to be a homework problem, and it'd be advisable that you solve that part yourself. 我不会深入研究逻辑的正确性,因为它似乎是一个家庭作业问题,建议您自己解决这部分问题。

You cannot free the node and then access it. 您不能释放该节点然后再访问它。 Try to move the free after the temp1=temp1->left . 尝试在temp1=temp1->left之后移动自由temp1=temp1->left Also, you must return once you found the correct node or path (or use else if): 另外,一旦找到正确的节点或路径,就必须返回(或在其他情况下使用):

delete_tree_node(int delete_val, node **root)
{
  node *temp1;
  temp1 = *root;
  if(delete_val == temp1->freq)
  {    
     temp1 = temp1->left;    
     free(*root);    
     *root = temp1;     
  }   
  else if(delete_val < temp1->freq)    
  { 
     delete_tree_node(delete_val, &temp1->left);    
  }
  else if(delete_val > temp1->freq)    
  {
     delete_tree_node(delete_val, &temp1->right);
  }    
}
 temp1=(*root); // copying  the memory address of node to temp1   
 free((*root));    // your freeing the memory here of the node 
 temp1=temp1->left;    // the memory your accessing is already free'd hence segmentation fault occurs

try interchanging the two statements . 尝试交换两个陈述。

temp1=temp1->left;
free((*root));

regarding the reference for logic check here 关于此处的逻辑检查参考

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

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