从二叉搜索树中删除元素

时间:2016-02-22 07:52:04

标签: c++ binary-search-tree

这是我的Binarysearchtree.h。当必须删除的元素有一个子元素时,remove函数不起作用。

#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
////////////////////////////////

该节目适用于节点没有孩子或两个以上孩子而不是一个孩子的情况。

/*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();

}

/我不知道只是评论,因为我的问题需要更多上下文 /

1 个答案:

答案 0 :(得分:0)

这是我前一段时间用C ++中的二进制搜索树删除节点的代码:

基本上,如果要删除没有子节点的节点,只需将父节点指针设置为null,然后再删除它。容易腻。

如果节点有子节点,我们需要将这些子节点链接到我们正在删除的节点的父节点 - 这有点困难。

如果我们要删除根节点,请在删除它之前给它一个假的父节点,并将其与其中一个子节点交换。

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

完整的解决方案:

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