二叉搜索树中的 C++ 删除

c++ delete in binary search tree

本文关键字:C++ 删除 搜索树      更新时间:2023-10-16

我有一个二叉搜索树,由以下节点组成:

struct ProductNode
{
    Product data;
    ProductNode* left;
    ProductNode* right;
};

我有一个删除函数,它采用产品节点指针参数:

void ProductCategory::deleteandnull(ProductNode * p) 
{
    if(p!=NULL)
    {
        delete p;
        p=NULL;
    }
}

我对删除方法没有问题。添加新叶子时,左右指针为 NULL,但是当我使用此功能时,我看到没有删除,此操作不会更改二叉搜索树。这是什么问题?

改用这个:

void ProductCategory::deleteRightChild(ProductNode * p) 
{
    if(p->right!=NULL)
    {
        delete p->right;
        p->right = NULL;
    }
}

为左孩子写一个等效的词条。

您的函数不起作用,因为您不更改父节点的内容。 它仍然具有已删除节点的地址,因此(如果此内容被重新定位到其他地方并更改(它可以访问它......!

但内存确实是解除分配的。

编辑:此答案基于OP得出"没有删除"的结论的假设,因为他希望在调用位置看到一个空指针。如果不是这种情况,他将需要澄清导致这一结论的原因。没有理由认为OP的代码没有删除p指向的任何内容。

p按值传递到 deleteandnull 函数中。因此,只有指针的本地副本设置为 NULL 。假设你在某处有这样的代码:

ProductNode *ptr = // Somehow initialize to the parent of the node to delete
.
.
deleteandnull(ptr->left);

您需要在调用 deletandnull 后添加此内容

ptr->left = NULL;

请注意,在调用 delete 之前,无需测试 NULL。它自己也会这样做。而且由于deleteandnull中的p是本地的,因此没有必要将其设置为 NULL .因此,整个代码也可以简化为:

ProductNode *ptr = // Somehow initialize to the parent of the node to delete
.
.
delete ptr->left;
ptr->left = NULL;

综上所述,在现代C++中,您不应该使用裸指针,newdelete。更喜欢使用智能指针,例如在 Boost 库中。

   Procedure :
   1. At first locate the node to be deleted.
   2. If the node is a leaf node :
   i. If the node is left child of the parent , make null the left pointer of its parent node and free the space for the node.
   ii. If the node is right child of the parent , make null the right pointer of its parent node and free the space for the node.
   3. If the node has one child
    i. If the node to be deleted is a left chile of its parent , then make link between the left pointer of its parent node and the child node to be deleted. Then delete the node.
    ii.If the node to be deleted is a right child of its parent , then make link between the right pointer of its parent node and the child node to be deleted. Then delete the node.
   4. If the node to be deleted has two child :
     i. Locate the node with maximum value from the left sub-tree of  the node to be deleted.
     ii. Replace the node value to be deleted by the node found in step 4(i)
   5. Now we get updated output

C++实现:

    node* Delete(node *root, int data)
    {
      if(root == NULL) return root;
      else if(data < root->data) root->left = Delete(root->left,data);
      else if (data > root->data) root->right = Delete(root->right,data);
      else
      {
       ///Case 1:  No child
      if(root->left == NULL && root->right == NULL)
      {
        delete root;
        root = NULL;
      }
      ///Case 2: One child
      else if(root->left == NULL)
      {
        struct node *temp = root;
        root= root->right;
        delete temp;
      }
      else if(root->right == NULL)
      {
        struct node *temp = root;
        root = root->left;
        delete temp;
      }
      ///case 3: 2 children
       else
       {
         node *temp = FindMin(root->right);
         root->data = temp->data;
         root->right = Delete(root->right,temp->data);
       }
     }
    return root;  
}