C++ 在二元搜索树中删除元素时出错

C++ 在二元搜索树中删除元素时出错,c++,data-structures,tree,C++,Data Structures,Tree,我只使用函数insert、remove和middorder #include<iostream> template<class Elem> class BinNode { public: virtual Elem& getVal() = 0; }; template<class Elem> class BinNodePtr:public BinNode<Elem> { public: Elem val; BinN

我只使用函数
insert
remove
middorder

#include<iostream>

template<class Elem>
class BinNode
{
public:
    virtual Elem& getVal() = 0;
};

template<class Elem>
class BinNodePtr:public BinNode<Elem>
{
public:
    Elem val;
    BinNodePtr* lc;
    BinNodePtr* rc;
    BinNodePtr()
    {
        lc = rc = NULL;
    }
    ~BinNodePtr()
    {
        delete lc;
        delete rc;
    }
    Elem& getVal()
    {
        return this->val;
    }
};

template<class Elem>
class BST
{
public:
    BinNodePtr<Elem> *root;
    int nodenum;
    void midorder(BinNodePtr<Elem>* start);
public:
    BST()
    {
        root = NULL;
        nodenum = 0;
    }
    bool insert(BinNodePtr<Elem>*&ptr,const Elem &e);//
    void remove(BinNodePtr<Elem>*&start,const Elem &e);//
    BinNodePtr<Elem>* getRoot(){return root;}
};

template<class Elem>
void BST<Elem>::midorder(BinNodePtr<Elem> *start)
{
    if(start == NULL) return;
    midorder(start->lc);
    printf("%d ",start->getVal());
    midorder(start->rc);
}

template<class Elem>
bool BST<Elem>::insert(BinNodePtr<Elem>*&ptr,const Elem &e)
{
    if(ptr == NULL)
    {
        ptr = new BinNodePtr<Elem>;
        ptr->lc = NULL;
        ptr->rc = NULL;
        ptr->val = e;
        return true;
    }
    else
    {
        if(ptr->val < e || ptr->val == e)
        {
            insert(ptr->rc,e);
        }
        else
        {
            insert(ptr->lc,e);
        }
    }
    return false;
}

template<class Elem>
void BST<Elem>::remove(BinNodePtr<Elem>*&start,const Elem &e)
{
    if(start == NULL)
        return ;
    if(start->val < e)
        remove(start->rc,e);
    else if(start->val > e)
        remove(start->lc,e);
    else
    {
        if(start->lc == NULL && start->rc == NULL)
        {
            delete start;
        }
        else if(start->lc == NULL)
        {
            BinNodePtr<Elem> *temp = start;
            start = start->rc;
            delete (temp);
        }
        else if(start->rc == NULL)
        {
            BinNodePtr<Elem> *temp = start;
            start = start->lc;
            delete temp;
        }
        else
        {
            BinNodePtr<Elem>* temp = start->rc;
            while(temp->lc!= NULL)
            {
                temp = temp->lc;
            }
            start->val = temp->val;
            remove(start->rc,temp->val);
        }

    }
}
int main()
{
    BST<int> myBST;
    (myBST.insert(myBST.root,10));
    (myBST.insert(myBST.root,20));
    (myBST.insert(myBST.root,5));
    (myBST.insert(myBST.root,30));
    myBST.midorder(myBST.getRoot());
    myBST.remove(myBST.root,10);
    myBST.midorder(myBST.getRoot());
    system("pause");
    return 0;
}
#包括
模板
类二进制节点
{
公众:
虚拟元素&getVal()=0;
};
模板
类BinNodePtr:public BinNode
{
公众:
元素val;
BinNodePtr*lc;
BinNodePtr*rc;
BinNodePtr()
{
lc=rc=NULL;
}
~BinNodePtr()
{
删除信用证;
删除rc;
}
Elem&getVal()
{
返回此->val;
}
};
模板
BST级
{
公众:
BinNodePtr*根;
int nodenum;
作废中订单(BinNodePtr*start);
公众:
BST()
{
root=NULL;
nodenum=0;
}
bool插件(BinNodePtr*&ptr,常量元素和电气)//
无效删除(BinNodePtr*&start,const Elem&e)//
BinNodePtr*getRoot(){return root;}
};
模板
void BST::中订单(BinNodePtr*start)
{
if(start==NULL)返回;
中间订单(开始->信用证);
printf(“%d”,start->getVal());
中间订单(开始->rc);
}
模板
bool BST::插入(BinNodePtr*&ptr,常量元素和元素)
{
如果(ptr==NULL)
{
ptr=新的BinNodePtr;
ptr->lc=NULL;
ptr->rc=NULL;
ptr->val=e;
返回true;
}
其他的
{
如果(ptr->valval==e)
{
插入(ptr->rc,e);
}
其他的
{
插入(ptr->lc,e);
}
}
返回false;
}
模板
void BST::remove(BinNodePtr*&start,const Elem&e)
{
if(start==NULL)
返回;
如果(开始->值rc,e);
否则如果(开始->值>e)
移除(开始->lc,e);
其他的
{
如果(开始->lc==NULL&&start->rc==NULL)
{
删除开始;
}
否则如果(开始->lc==NULL)
{
BinNodePtr*temp=启动;
开始=开始->钢筋混凝土;
删除(临时);
}
else if(开始->rc==NULL)
{
BinNodePtr*temp=启动;
开始=开始->lc;
删除临时文件;
}
其他的
{
BinNodePtr*temp=start->rc;
同时(临时->lc!=NULL)
{
温度=温度->lc;
}
开始->值=温度->值;
移除(开始->rc,临时->val);
}
}
}
int main()
{
BST myBST;
(myBST.insert(myBST.root,10));
(myBST.insert(myBST.root,20));
(myBST.insert(myBST.root,5));
(myBST.insert(myBST.root,30));
myBST.midorder(myBST.getRoot());
移除myBST.remove(myBST.root,10);
myBST.midorder(myBST.getRoot());
系统(“暂停”);
返回0;
}

我已经成功地插入了10、20、5、30,因为我可以
将它们打印出来,但是当我使用函数
remove
时,程序崩溃了。我对此进行了调试,发现函数
remove
中有错误,但我不知道如何修复它。

我快速查看了一下。如果您单步执行
remove
功能,您会注意到您实际上删除了包含
20
的节点,而不是包含
10
的节点。但是我已经用20覆盖了包含10的节点,因此我可以删除包含20的节点。我看到的一个问题是,您没有在“If”的情况下重置“start”(start->lc==NULL&&start->rc==NULL)“让它成为一个悬空指针如果你调试了它,你应该能够比“有问题”更具体。哪一行出现问题?您是否评估了所有适用的变量,并将它们追溯到初始化它们的位置,以确保所有变量都已正确设置?在insert中,除了您应该返回insert(…)之外,看起来还可以函数remove包含多个指针悬空的错误,最好在纸上写下您想做的事情,然后重新实现。