简体   繁体   中英

Function to delete node with given value from a binary search tree

I have a struct called TreeNode with an int key, and left right and parent. I am trying to delete a node from a tree with my DeleteNode function and it is not working. I am supposed to replace the deleted node in my DeleteNode function with the max value from the left subtree. My transplant and max functions are helper functions for DeleteNode. My issue is I'm not sure where in my DeleteNode function I should be comparing the node value I am at to the value I am passing in through the function. I have a comment in my code with astericks where I'm confused what to do. Any help would be greatly appreciated!

void transplant(TreeNode* u, TreeNode* v)   //swaps u with v
{

if (u->parent == NULL)  //if u was root, make v new root
    u->parent = v;
else if (u == u->parent->left)  //if u is smaller than it's parent
    u->parent->left = v;        //set v to the left child of parent of u. Swap them at left, really
else
    u->parent->right = v;       //otherwise swap them at right

if (v != NULL)              //reassign parents to double link
    v->parent = u->parent;
}

TreeNode* maximum(TreeNode* n)
{

while (n->left != NULL)
    n = n->left;
return n;
}

  void deleteNode(TreeNode *node, int key)
{

if (node->left == NULL)                 //if there is no left child
    transplant(node, node->right);      //swap 
else if (node->right == NULL)           //if there is no right child
    transplant(node, node->left);       //swap 
else 
{
  if(node->key == key){ //****This if comparison must be wrong***
    TreeNode* temp = maximum(node->right);  //make temp the max on right
    if (temp->parent != node )              //if it is more than one chain down
    {
        transplant(temp, temp->right);          //swap temp and it's right branch
        temp->right = node->right;          //set right branch to nodes right
        temp->parent->right = temp;             //set temp to the right child 
    }
    transplant(node, temp);                 // transplant
    temp->left = node->left;                //get nodes left branch
    temp->left->parent = temp;              //replace
    }
}
}

Firstly, you have three cases to handle: (Straight from wikipedia. Was great for me when I took data structures)

There are three possible cases to consider:

Deleting a node with no children (leaf): simply remove the node from the tree.

Deleting a node with one child: remove the node and replace it with its child.

Deleting a node with two children: call the node to be deleted N. Do not delete N. Instead, choose either its in-order successor node or its in-order predecessor node, R. Copy the value of R to N, then recursively call delete on R until reaching one of the first two cases.

Broadly speaking, nodes with children are harder to delete. As with all binary trees, a node's in-order successor is its right subtree's left-most child, and a node's in-order predecessor is the left subtree's right-most child. In either case, this node will have zero or one children. Delete it according to one of the two simpler cases above.

You appear to be attempting to implement the in-order successor option because of maximum(node->right).

Now that we have established your possible cases, the only case that really necessitates transplant is the third case, with two children, in my opinion.

case 1: simply call delete on the leaf node.

case 2:

Here, del is the node to be deleted (del has one right child in this case). I just wrote this up real quick. The first if statement checks if del is the left child of its parent node, then "removes" itself from the pointer equation by pointing its parent to its child, and vice versa. The second if does the same, but instead checks if del is the right child of its parent node. Lastly, delete the node.

del->right->parent = del->parent;
if (del == del->parent->left)
    del->parent->left = del->right;
else if (del == del->parent->right)
    del->parent->right = del->right;
delete del;

case 3:

TreeNode *inOrderSuccessor = maximum(del->right);
del->val = inOrderSuccessor->val; //you could use transplant/swap here
deleteNode(inOrderSuccessor, inOrderSuccessor->val);

That's about it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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