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

时间:2014-03-03 11:49:25

标签: c algorithm data-structures binary-tree binary-search-tree

我正在尝试删除二叉树,我的程序工作如下:

(1)它读取树中要创建的节点数。

(2)它读取所有这些节点。

(3)打印由这些节点形成的树。

(4)它在终端读取要删除的节点。

直到这里一切正常但是当我尝试删除所需的节点时,它会给出分段错误错误。

注意:我必须通过引用传递root(这就是为什么我在delete_tree_node(int delete_val,node ** root)中为root保留了两个指针)。

我这样做的方法是: 我通过左右子进行递归调用函数delete_tree_node()以遍历树,直到我得到node的值等于用户想要删除的节点的值。如果我得到那个地方,那么我free()那个节点。

我实现此目的的代码是:(这会产生分段问题):

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

它的函数调用是:

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

有人可以帮助我知道:

(1)为什么会出现分段错误。

(2)删除所需节点的逻辑是否正确?如果没有,那么请您给我一段代码作为参考吗?

3 个答案:

答案 0 :(得分:2)

  

为什么会出现分段错误?

因为在尝试访问*root中的相同内存之前释放temp1->left指向的内存。

让我们仔细研究一下: -

temp1 = (*root)

temp1现在保持与(* root)相同的内存地址,即两者都是指向同一地址的一些数字。为清楚起见,我们假设该数字为“6”。因此,它们都指向内存地址'6'。注意,它们不等于该地址的值,而只是指向它。

现在,free((*root));告诉系统您正在释放(* root)指向的内存位置,在本例中为6.一旦释放内存,就会失去对该内存的访问权限。你提出请求的时间(通过temp1->left),你会得到分段错误。

我希望澄清导致分段错误的原因。

粗略的一瞥告诉我你可以通过释放(* root)来解决这个问题。事实上,递归调用会更加清晰,因为你可以通过这个伪代码来描述: -

delete left subtree
delete right subtree
delete root

我不会深入研究逻辑的正确性,因为它似乎是一个家庭作业问题,你最好自己解决这个问题。

答案 1 :(得分:1)

您无法释放节点然后访问它。尝试在temp1=temp1->left之后移动免费。 此外,您必须在找到正确的节点或路径后返回(或使用其他方式):

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

答案 2 :(得分:1)

 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

尝试交换这两个陈述。

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

关于逻辑check here

的参考