简体   繁体   English

二进制搜索树中的删除

[英]Deletion in binary search tree

So when I delete in binary search tree, do I need to have like 7 different cases ie 所以当我在二分搜索树中删除时,我是否需要有7种不同的情况,即

  1. Left Leaf; 左叶;
  2. Right Leaf; 右叶;
  3. Left child with only left child. 左子只有左子。 //ie the node to be deleted is the left child of it's parent and it has only left child. //即要删除的节点是其父节点的左子节点,并且只有左子节点。
  4. Left Child with only right child. 左子与唯一的右子。
  5. Right child with only left child. 右子只有左子。
  6. Right child with only right child. 合适的孩子,只有合适的孩子。
  7. Node to be deleted has both the children ie right and left. 要删除的节点有两个子节点,即右和左。

Now when this code is using if-else it gets pretty nasty.. is there any other way of doing this. 现在,当此代码使用if-else它变得非常讨厌..还有其他方法可以做到这一点。

Here is my code snippet 这是我的代码片段

if(current->left==NULL && current->right==NULL && current->key<prev->key)   //left leaf
prev->left=NULL;
else if(current->left==NULL && current->right==NULL && current->key>prev->key) // right     leaf
prev->right=NULL;
else if(current->left!=NULL && current->right==NULL && current->key<prev->key) // left     child with one child
prev->left=current->left;
else if(current->left==NULL && current->right!=NULL && current->key<prev->key)
prev->left=current->right;
else if(current->left!=NULL && current->right==NULL && current->key>prev->key)
prev->right=current->left;
else if(current->left==NULL && current->right!=NULL && current->key>prev->key)
prev->right=current->left;
else if(current->left!=NULL && current->right!=NULL)
{
    check=current->right;
    check1=check;
    while(check->left!=NULL)
    {
    check1=check;
    check=check->left;
    }
    *current=*check;
    check1->left=NULL;
}

You can keep it a lot simpler than that, and simply restrict yourself to three cases when deleting a node from a BST (binary search tree) : 您可以使它比这简单得多,并且在从BST(二进制搜索树)中删除节点时,仅将自己限制为三种情况:

  1. a node without children (a leaf) : just remove it - nothing special needs to be done 没有子节点(叶子)的节点:只需将其删除-无需执行任何特殊操作
  2. a node with one child : remove it, and move the child in its place 一个有一个孩子的节点:将其删除,然后将孩子移动到其位置
  3. a node with two children : swap it with either its in-order predecessor or successor, and then remove it 一个有两个子节点的节点:将其与有序的前任节点或后继节点交换,然后将其删除

The wiki page contains an example of how this could look in code. Wiki页面包含一个示例,说明了它如何在代码中显示。

Or as a very basic example in C : 或作为C中一个非常基本的示例:

if (current->left==NULL && current->right==NULL) {
    /* leaf node */
    bst_replace(current, NULL);
}
else if (current->left==NULL || current->right==NULL) {
    /* node with one child */
    bst_replace(current, ((current->left) ? current->left : current->right));
}
else {
    /* node with two children */
    Node* successor = bst_next(current);
    current->data = successor->data;
    bst_replace(successor, successor->right);
}

I don't really understand the protocol used for deleting here. 我不太了解用于此处删除的协议。 You seem to not have a binary 'search' tree (no ordering in the tree). 您似乎没有二进制的“搜索”树(树中没有排序)。

But to just make the code simple. 但是只是使代码简单。 You could do something like this: 您可以执行以下操作:

bool b1 = (current->left == NULL);
bool b2 = (current->right == NULL);
bool b3 = (current->key > prev->key);

int decision_case = b1 * 4 + b2 * 2 + b3;

switch(decision_case) {
  case 0: // fill in code here
          break;
  ...
  ...
  case 7: // fill in code here
          break;
}

Also, you should use delete to avoid memory leaks here. 另外,您应该使用Delete来避免此处的内存泄漏。 Hope that helps. 希望能有所帮助。

Deleting a NULL pointer has no ill effect. 删除NULL指针不会有不良影响。 So, you should be able to do this with no special cases. 因此,您应该能够在没有特殊情况的情况下执行此操作。 The basic part is just: 基本部分是:

delete current->left;
delete current->right;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM