删除叶节点 BST

Deleting a Leaf node BST

我只是为了学习而尝试实现一个 AVL 树。我设法进行了插入,但我坚持删除。我在删除叶节点时遇到问题(one-child 案例工作得很好)。问题是,当我删除节点时,它不会从 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

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

删除节点时,需要更改其父节点的相应子字段。但是在您的代码中,您只传入要删除的节点本身 (node_t *root),因此父节点保持不变。在单个子节点的情况下,您可以通过将单个子节点复制到要删除的节点来解决它,然后删除单个子节点。但是在叶子的情况下,你没有做任何事情来修复 parent.

中的 link

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

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