从BST中删除元素(指针错误)

时间:2017-04-03 16:06:31

标签: c++ pointers

所以我在BST上有自己的实现。现在我需要实现remove_value函数,它将从我的树中删除具有该值的节点。我有这个简单的代码:

void binary_tree::remove_value(int value)
{
    if (!this->exists(value)) return; //if value doesnt exist - return
    nodeBST* current = root;
    nodeBST* prev = nullptr;
    bool left = true;
    while (true)
    {
        if (current->value == value) // when we find it
        {
            if (current->right == nullptr && current->left == nullptr) // 0 children
            {   
                delete current;
                this->n--;
                if (left) prev->left = nullptr;
                else prev->right = nullptr;
                //even tried delete current here
                return;
            }
            else if (current->right == nullptr && current->left != nullptr) // 1 lewe dziecko
            {
                if (left) prev->left == current->left;
                else prev->right == current->left;
                delete current;
                this->n--;
                return;
            }
            else if (current->right != nullptr && current->left == nullptr) // 1 prawe dziecko dziecko
            {
                if (left) prev->left == current->right;
                else prev->right == current->right;
                delete current;
                this->n--;
                return;
            }
            else if (current->right != nullptr && current->left != nullptr) // dwoje dzieci
            {
                nodeBST* tempNode = findMin(current);
                current->value = tempNode->value;
                remove_node(current, prev, left);
            }
        }
        else if (current->value > value)
        {
            prev = current;
            left = true;
            current = current->left;
        }
        else
        {
            prev = current;
            left = false;
            current = current->right;
        }
    }
}

我知道它有点混乱,所以我会告诉你它的作用。底部循环穿过树。如果我们搜索的值大于当前节点值previous becomes currentcurrent becomes current->rightleft = false。相反,当它较小时。现在看看if之后的第一个current->value == value - 这是应该为0个孩子执行的代码。现在,它确实删除了当前节点,但我遇到了问题。

我有一个打印功能,它占用了整棵树并打印出来。并且它会因某些指针错误而崩溃。我检查了。当我delete currentprev->leftprev->right(取决于left值)设置为0xdddddddd时,无论我在分配prev->后是否删除或之前。我甚至尝试delete prev->right/left然后分配nullptr,但仍然会发生同样的情况。如何删除节点,但仍然可以将nullptr分配给right节点的leftprev属性?

@Edit:

此代码与print(

一致失败
void binary_tree::print(std::string sp, std::string sn, nodeBST* v)
{
    if (this->is_empty()) return;
    std::string s;
    if (v)
    {
        s = sp;
        if (sn == cr) s[s.length() - 2] = ' ';
        print(s + cp, cr, v->right);

        s = s.substr(0, sp.length() - 2);
        std::cout << s << sn << v->value << std::endl;

        s = sp;
        if (sn == cl) s[s.length() - 2] = ' ';
        print(s + cp, cl, v->left);
    }
}

异常是(我从我的语言翻译),内存中有不需要的读取,以及v was 0xddddd

1 个答案:

答案 0 :(得分:1)

所以if (current->right == nullptr && current->left == nullptr)里面有一个错误。这段代码正在运行:

void binary_tree::remove_value(int value)
{
    if (!this->exists(value)) return; //if value doesnt exist - return
    nodeBST* current = root;
    nodeBST* prev = nullptr;
    bool left = true;
    while (true)
    {
        if (current->value == value) // when we find it
        {
            if (current->right == nullptr && current->left == nullptr) // 0 children
            {   
                delete current;
                this->n--;
                if(prev!=nullptr) {
                if (left) prev->left = nullptr;
                else prev->right = nullptr;
                }
                //even tried delete current here
                return;
            }
            else if (current->right == nullptr && current->left != nullptr) // 1 lewe dziecko
            {
                if(prev!=nullptr) {
                if (left) prev->left == current->left;
                else prev->right == current->left;}
                delete current;
                this->n--;
                return;
            }
            else if (current->right != nullptr && current->left == nullptr) // 1 prawe dziecko dziecko
            {
                if(prev!=nullptr) {
                if (left) prev->left == current->right;
                else prev->right == current->right;}
                delete current;
                this->n--;
                return;
            }
            else if (current->right != nullptr && current->left != nullptr) // dwoje dzieci
            {
                nodeBST* tempNode = findMin(current);
                current->value = tempNode->value;
                remove_node(current, prev, left);
            }
        }
        else if (current->value > value)
        {
            prev = current;
            left = true;
            current = current->left;
        }
        else
        {
            prev = current;
            left = false;
            current = current->right;
        }
    }
}