【问题标题】:Deleting a Leaf node BST删除叶子节点BST
【发布时间】:2015-07-05 22:03:25
【问题描述】:

我只是为了学习而尝试实现 AVL 树。我设法进行了插入,但我被困在删除中。我在删除叶节点时遇到问题(单子情况很好)。问题是当我删除节点时,它不会从 BST 中删除,相反,它的值只是变成 0,所以当节点被删除时,树永远不会不平衡。我基本上在做的是,如果我遇到一个没有孩子的节点,我只是释放它。这是函数的代码(没有重新平衡部分):

node_t *Delete ( node_t *root, int num ){

   if ( !root ){
     printf ("Not Found\n");
     return root;
   }

//=======Search for the Element=============

   if ( num > root->data )
       Delete ( root->right , num );

   else if ( num < root->data )
       Delete ( root->left , num );

//======Delete element==============

   else if ( num == root->data ){

     if ( root->right && root->left ){ //two child case

         node_t *auxP = root->right;

         while ( auxP->left ) //finding the successor 
            auxP=auxP->left; 

         root->data = auxP->data; 

         root->right = Delete ( root->right, auxP->data );     
     }

     else{ //one or no child

         if ( !root->right && !root->left ){ // no childs
           free(root);       
         }
         else{ //one child
             node_t *auxP = ( root->right ?  root->right : root->left );
             *root=*auxP;
             free(auxP);
         }                
     }  

   }
  return root;
}

如果我有一棵这样的树:

        10
       /  \
      5    15 
     / \    \
    2   6    17

我尝试删除6,就这样结束了

        10
       /  \
      5   15 
     / \    \
    2   0    17

这可能是一个明显的错误,但我找不到。任何关于它为什么不起作用的解释将不胜感激。

【问题讨论】:

标签: c binary-search-tree


【解决方案1】:

删除节点时,需要更改其父节点的相应子字段。但是在您的代码中,您只传递要删除的节点本身 (node_t *root),因此父节点保持不变。在单个子项的情况下,您可以通过将单个子项复制到要删除的节点来解决此问题,并改为删除单个子项。但是在叶子的情况下,你什么都不做来修复父级的链接。

一种方法是以某种方式传入父节点,以便当要删除的节点是叶子时,断开与父节点的链接并将父节点的相应子节点设置为NULL

或者,您可以将父链接添加到节点定义中,以便在删除节点时可以从中派生父链接。

【讨论】:

  • 感谢您的回复,确实,这就是问题所在。我更正了它,将递归调用(在搜索部分)分配给实际节点的左/右子节点,并在删除时返回 NULL,因此父节点的右/左子节点现在将为 NULL。
猜你喜欢
  • 1970-01-01
  • 2021-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-26
  • 2016-11-11
相关资源
最近更新 更多