简体   繁体   中英

Removing element from a binary search tree

Here is my Binarysearchtree.h . The remove function is not working when the element that has to be deleted has one child.

#ifndef BINARYSEARCHTREE_H_INCLUDED
#define BINARYSEARCHTREE_H_INCLUDED

class BinarySearchTreeNode {
    public:
    int data;
    BinarySearchTreeNode* left;
    BinarySearchTreeNode* right;

    BinarySearchTreeNode( int data):data(data), left(NULL), right(NULL) {
    }


    ~BinarySearchTreeNode() {
        if (left)
            delete left;
        if (right)
            delete right;
    }
    friend class BinarySearchTree;
};

class BinarySearchTree
{
    private:
     int size;

    public:
    BinarySearchTreeNode * root;

    BinarySearchTree()
    {
        size=0;
        root= NULL;
    }

    private:
    void insert_help(BinarySearchTreeNode*root,BinarySearchTreeNode*node)
    {
        if(root==NULL)
           {
               this->root=node;
               return;
           }

         if(node->data>root->data and root->right==NULL)
                {
                    root->right=node;
                    return;
                }
          if(node->data<=root->data and root->left==NULL)
                {
                   root->left=node;
                    return;
                }

        if(node->data<=root->data)
            insert_help(root->left,node);
        if(node->data>root->data)
            insert_help(root->right,node);




    }


   public:
    void insert(int data)
    {
        BinarySearchTreeNode* newnode=new BinarySearchTreeNode(data);
        size++;
        insert_help(this->root,newnode);

    }

    void printLevelWise()
{
    if(root==NULL)
        return;

   queue<BinarySearchTreeNode*> pending;
   pending.push(root);
   while(pending.empty()!=1)
   {
       BinarySearchTreeNode*latest=pending.front();
       pending.pop();
       cout<<latest->data<<": ";
       if(latest->left)
       {
           cout<<latest->left->data<<",";
       pending.push(latest->left);
       }
       if(latest->right)
        {
            cout<<latest->right->data<<",";
            pending.push(latest->right);
        }
        cout<<"\n";
   }
}


bool isEmpty()
{
    if(root==NULL)
        return true;
    else
        return false;
}

int Size()
{
    return size;
}

   private:
       BinarySearchTreeNode* Search_help(BinarySearchTreeNode*root,int data)
       {
           if(root==NULL or root->data==data)
        return root;

    if(data>root->data)
       return Search_help(root->right,data);
    if(data <= root->data)
       return Search_help(root->left,data);



       }



public:

BinarySearchTreeNode* Search(int data)
{
  return Search_help(root,data);


}
private:

 BinarySearchTreeNode*return_min(BinarySearchTreeNode*root)
 {
     if(root->left==NULL)
        return root;
     return return_min(root->left);
 }

/*this is my remove function*/
BinarySearchTreeNode* remove_help(BinarySearchTreeNode*root,int data) 

{
    if(root==NULL)
        return root;

    if(data>root->data)
      root->right=  remove_help(root->right,data);

   else if(data<root->data)
        root->left=remove_help(root->left,data);

    else
    {
        //no child
        if(root->left==NULL and root->right==NULL)
        {
            delete root;
            return NULL;
        }
         //one child
         if(root->left==NULL)
         {
             BinarySearchTreeNode*temp=root->right;

             delete root; // when i remove this line the code works idk why
             return temp;  

         }
         if(root->right==NULL)
         {
             BinarySearchTreeNode*temp=root->left;
             delete root;
             return temp;

         }
         //more than one child

         BinarySearchTreeNode*temp=return_min(root->right);
         root->data=temp->data;
         root->right=remove_help(root->right,temp->data);



    }

    return root; 
    }

public:
void Remove(int data)
{
    root=remove_help(root,data);
    return;

}

};

#endif // BINARYSEARCHTREE_H_INCLUDED
////////////////////////////////

This program is working for when the node has no child or more than two childs but not one child.

/*here is my main program*/

#include<iostream>
#include"tree.h"
#include<limits.h>
#include<math.h>
#include<stack>
#include"BinaryTree.h"
#include"linked_list.h"
#include<vector>
#include"BinarySearchTree.h"
using namespace std;

int main()
{
BinarySearchTree bst;
bst.insert(6);
bst.insert(3);
bst.insert(9);
bst.insert(4);
bst.insert(8);
bst.printLevelWise();

bst.Remove(9);

bst.printLevelWise();

}

/i dont know just commenting as my question needed more context /

Here is the code I wrote awhile ago to remove a node from a binary search tree in C++:

Basically, if you're deleting a node that has no children, you just set the parent node pointer to null before deleting it. Easy peasy.

If the node has children, we need to link those children to the parent of the node we are deleting - a little more difficult.

If we're deleting the root node, give it a fake parent before deleting it, and swap it with one of the children.

///////////////////////////////
// DeleteID Function:
///////////////////////////////
bool Tree::deleteID(int id) {
    if(root == NULL)
        return false;
    Node *toDelete = findNode(id);      //Find the node to delete
    if(toDelete == NULL)                //If we can't find it, return false
        return false;
    Node *parent = findParent(id);      //Find the parent of the node to delete
    Node *justInCase;                   //In case we are deleting the root node
    bool deletingRoot = false;          //This is a special case so handle it differently
    if(root->id == id) {                //If we're deleting the root node
        justInCase = new Node();        //Let's create a fake parent for the root
        justInCase->leftChild = root;   //Just to make sure that we can run checks on parents
        justInCase->rightChild = NULL;
        justInCase->id = 0;             //Later on in the code
        parent = justInCase;            //Set the parent of the root to our new fake node
        deletingRoot = true;            //Let the end of our function know we're deleting the root
    }
    bool deletingLeftChild = (parent->leftChild == toDelete);
    if(toDelete->leftChild == NULL && toDelete->rightChild == NULL) {
        if(toDelete == root)
            root = NULL;
        if(deletingLeftChild)
            parent->leftChild = NULL;
        else
            parent->rightChild = NULL;
        delete toDelete;
        return true;
    }
    if((toDelete->leftChild == NULL || toDelete->rightChild == NULL) && (parent != NULL && !deletingRoot)) {
        if(deletingLeftChild)
            parent->leftChild = (toDelete->leftChild == NULL) ? toDelete->rightChild : toDelete->leftChild;
        else
            parent->rightChild = (toDelete->leftChild == NULL) ? toDelete->rightChild : toDelete->leftChild;
        delete toDelete;
        return true;
    }
    Node *replacer = findMaximum(toDelete->leftChild);          //Replace the node we're deleting with the hightest LEFT Child
    if(replacer == NULL || replacer == toDelete)                //If we can't find a left child (in case of deleting root)
        replacer = findMinimum(toDelete->rightChild);           //Find the smallest RIGHT child
    Node *replacerParent = findParent(replacer->id);            //Find the parent of this child
    if(replacerParent != NULL) {                                //If this child has a parent
        if(replacerParent->leftChild == replacer) {             //If the child is to the left of the parent
            if(replacer->leftChild != NULL)                     //And the left child has a child of its own (in case of findMinimum/maximum)
                replacerParent->leftChild = replacer->leftChild;//set the parent's child to this child's node
            else
                replacerParent->leftChild = NULL;               //Otherwise, set the parent's child to NULL
        }
        else {                                                  //In the case of Right Child
            if(replacer->rightChild != NULL)                    //Do the same thing
                replacerParent->rightChild = replacer->rightChild;
            else
                replacerParent->rightChild = NULL;
        }
    }
    toDelete->id = replacer->id;                                //Swap the IDs of the nodes we're deleting
    delete replacer;                                            //And delete the minimum or maximum that we found
    return true;
}

Complete solution:

https://stackoverflow.com/a/10084855/1274820

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