C++ Delete node方法不实际删除二叉搜索树中的节点。C++;

C++ Delete node方法不实际删除二叉搜索树中的节点。C++;,c++,c++11,binary-tree,binary-search-tree,C++,C++11,Binary Tree,Binary Search Tree,当我调用removeNode方法时,它显示在本地删除节点并在调试器中将其设置为null,但是当我查看调试器中的树时,应该删除的节点仍然存在。当我打印树时,应该被删除的节点会打印出来,但是分配给结构的int和string会打印出来 我尝试过使用free()和delete,但实际上都没有删除节点 bool BinTree::addNode(int id, string info, DataNode *add_node) { auto *temp_node = new DataNode;

当我调用removeNode方法时,它显示在本地删除节点并在调试器中将其设置为null,但是当我查看调试器中的树时,应该删除的节点仍然存在。当我打印树时,应该被删除的节点会打印出来,但是分配给结构的int和string会打印出来

我尝试过使用free()和delete,但实际上都没有删除节点

bool BinTree::addNode(int id, string info, DataNode *add_node) {
    auto *temp_node = new DataNode;
    temp_node->data.id = id;
    temp_node->data.information = info;
    temp_node->left = temp_node->right = nullptr;

    if(id < add_node->data.id){
        if(!add_node->left){
            add_node->left = new DataNode;
            add_node->left = temp_node;
            count++;
        }else{
            addNode(id, info, add_node->left);
        }
    }else{
        if(!add_node->right){
            add_node->right = new DataNode;
            add_node->right = temp_node;
            count++;
        }else{
            addNode(id, info, add_node->right);
        }
    }
}

bool BinTree::removeNode(int id, DataNode *temp_root) {
    cout << "Searching to remove: " << id << endl;
    if(temp_root == nullptr){
        return false;
    }
    else if(id < temp_root->data.id) {
        removeNode(id, (temp_root->left);
    }
    else if(id > temp_root->data.id){
        removeNode(id, temp_root->right);
    }
    else{
        //no child
        if(temp_root->left == nullptr && temp_root->right == nullptr){
            cout << "Deleting no children node" << endl;            //DEBUG ONLY
            cout << "Temp root address:" << temp_root << endl;      //DEBUG ONLY
            delete temp_root;
            temp_root->data.id = 123456;                            //DEBUG ONLY
            cout << "no child deleted" << endl;                     //DEBUG ONLY
            count--;
        }
        //one child
        else if(temp_root->left == nullptr){
            cout << "Deleting 1 child node" << endl;
            DataNode *temp_node = temp_root;
            temp_root = temp_root->right;
            delete temp_node;
            temp_node = nullptr;
            count--;
        }
        else if(temp_root->right == nullptr){
            cout << "Deleting 1 child node" << endl;
            DataNode *temp_node = temp_root;
            temp_root = temp_root->left;
            free(temp_node);
            temp_node = nullptr;
            count--;
        }
        //two children
        else if(temp_root->left && temp_root->right){
            cout << "Deleting 2 child node" << endl;
            DataNode temp_node = minValueNode(temp_root->right);
            temp_root->data = temp_node.data;
            removeNode(temp_node.data.id, temp_root->right);
        }
        return true;
    }
}

DataNode BinTree::minValueNode(DataNode *temp_node) {
    while(temp_node->left){
        temp_node = temp_node->left;
    }
    return *temp_node;
}
bool BinTree::addNode(int-id,string-info,DataNode*add\u节点){
自动*临时节点=新数据节点;
temp_节点->data.id=id;
temp_节点->data.information=info;
临时节点->左=临时节点->右=空PTR;
if(iddata.id){
如果(!添加节点->左){
添加\节点->左=新建数据节点;
添加_节点->左=临时_节点;
计数++;
}否则{
添加节点(id、信息、添加节点->左侧);
}
}否则{
如果(!添加节点->右侧){
添加\节点->右=新建数据节点;
添加_节点->右=临时_节点;
计数++;
}否则{
addNode(id,info,add_node->right);
}
}
}
bool BinTree::removeNode(int-id,DataNode*temp\u root){
cout temp_root->data.id){
移除节点(id,临时根->右侧);
}
否则{
//没有孩子
if(temp\u root->left==nullptr&&temp\u root->right==nullptr){

就我个人而言,我会写remove来返回链接的新值

void removeNode(int id) {
    root = removeNode(id, root);
}
Node* removeNode(int id, Node* n) {
    if (n == nullptr) {
        return nullptr;
    }

    if (id < n->id) {
        n->left = removeNode(id, n->left);
        return n;
    }
    else if (n->id < id) {
        n->right = removeNode(id, n->right);
        return n;
    }
    else if (n->left == null) {
         Node* result = n->right;
         delete n;
         return result;
    }
    else if (n->right == null) {
         Node* result = n->left;
         delete n;
         return result;
    }
    else {
         int v = findSmallestValue(n->right);
         n->right = removeNode(v, n->right);
         n->id = v;
         return n;
    }
}
void removeNode(int-id){
root=removeNode(id,root);
}
节点*removeNode(int-id,节点*n){
如果(n==nullptr){
返回空ptr;
}
如果(idid){
n->left=removeNode(id,n->left);
返回n;
}
否则如果(n->idright=removeNode(id,n->right);
返回n;
}
else如果(n->left==null){
节点*结果=n->右侧;
删除n;
返回结果;
}
如果(n->right==null),则为else{
节点*result=n->left;
删除n;
返回结果;
}
否则{
int v=FindCallestValue(n->右侧);
n->right=removeNode(v,n->right);
n->id=v;
返回n;
}
}

我个人会编写remove来返回链接的新值

void removeNode(int id) {
    root = removeNode(id, root);
}
Node* removeNode(int id, Node* n) {
    if (n == nullptr) {
        return nullptr;
    }

    if (id < n->id) {
        n->left = removeNode(id, n->left);
        return n;
    }
    else if (n->id < id) {
        n->right = removeNode(id, n->right);
        return n;
    }
    else if (n->left == null) {
         Node* result = n->right;
         delete n;
         return result;
    }
    else if (n->right == null) {
         Node* result = n->left;
         delete n;
         return result;
    }
    else {
         int v = findSmallestValue(n->right);
         n->right = removeNode(v, n->right);
         n->id = v;
         return n;
    }
}
void removeNode(int-id){
root=removeNode(id,root);
}
节点*removeNode(int-id,节点*n){
如果(n==nullptr){
返回空ptr;
}
如果(idid){
n->left=removeNode(id,n->left);
返回n;
}
否则如果(n->idright=removeNode(id,n->right);
返回n;
}
else如果(n->left==null){
节点*结果=n->右侧;
删除n;
返回结果;
}
如果(n->right==null),则为else{
节点*result=n->left;
删除n;
返回结果;
}
否则{
int v=FindCallestValue(n->右侧);
n->right=removeNode(v,n->right);
n->id=v;
返回n;
}
}

delete temp\u root;temp\u root->data.id=123456;
是未定义的行为。删除指针后不能使用指针,除非将其重新分配到另一个有效地址。我这样做是为了检查代码的输出,而不是胡言乱语,它将在整数中显示123456。只是用来验证它实际上不是正在删除。变量
temp_node
temp_root
是函数的本地变量。您没有更改实际树中的任何节点,只是更改本地变量。只是用于验证它实际上没有被删除。这不是有效的测试。取消引用已删除指针是未定义的行为。如何传递实际值of root到temp_root?我的印象是这样传递它可以让我直接修改树。
delete temp_root;temp_root->data.id=123456;
是未定义的行为。除非您将指针重新分配到另一个有效地址,否则删除后不能使用指针。我这样做是为了检查代码的输出并安装它胡言乱语的ad它将在整数中显示123456。只是用于验证它实际上没有被删除。变量
temp_node
temp_root
是函数的局部变量。您没有更改实际树中的任何节点,只是局部变量。只是用于验证它实际上没有被删除。这不是有效的test.取消引用已删除的指针是一种未定义的行为。如何将root的实际值传递给temp_root?我的印象是这样传递会允许我直接修改树。我看不出这是一个没有子节点的节点的原因,但我可能读错了。@justenc94您不需要它。如果一个节点没有子节点如果(n->left==null),则左侧和右侧的子项都为null。因此,它将被
else捕获{
删除当前节点,并返回右节点作为此位置的新节点。右节点已为空,因此我们得到正确的行为。我不认为这是没有子节点的节点的原因,但我可能读错了。@justenc94您不需要它。如果节点没有子节点,则左和右都是如果(n->left==null){
删除当前节点并返回右节点作为该位置的新节点,则它将被
else捕获。右节点已经为null,因此我们得到正确的行为。