簡體   English   中英

二進制搜索樹中的c ++ delete

[英]c++ delete in binary search tree

我有一個二進制搜索樹,包括如下節點:

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

我有一個刪除函數,它接受ProductNode指針參數:

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

為左孩子寫一個等價的函數。

您的功能不起作用,因為您不更改父節點的內容。 它仍然有被刪除節點的地址所以(如果這個內容在其他地方被真實地定位並且已經改變)它可以訪問它......!

但內存真的被釋放了。

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

編輯:這個答案是基於OP假設“沒有刪除”的假設,因為他期望在調用位置看到一個NULL指針。 如果情況並非如此,他將需要澄清導致該結論的原因。 因為沒有理由認為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庫中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM