【问题标题】:Using "delete" on one pointer deletes a second pointer (Binary Search Tree)在一个指针上使用“删除”会删除第二个指针(二叉搜索树)
【发布时间】:2015-11-17 06:54:17
【问题描述】:

这是一个任务;我不能使用智能指针。这是我感觉正在发生的事情的视觉表示:

使用 Main.cpp 中的 myTree.remove(4) 后在调试器中创建树:

当我在二叉搜索树的 removeRec 函数中调用 delete temp 时,BTNode* x 从正确指向 2 变为错误地分配给像 temp 这样的随机存储器。显然,我希望 4 消失,BTNode* x 指向 2。这是我的构造函数/析构函数有问题吗?

独立的 RemoveRec 函数:

bool BinarySearchTree::remove(int data){
    return removeRec(root, data);
}

bool BinarySearchTree::removeRec(BTNode* &x, int data){
    if (x == NULL){
        return false;
    }
    else {
        if (data < x->data){
            return removeRec(x->left, data);
        }
        else if (data > x->data){
            return removeRec(x->right, data);
        }
        else // Found item
        {
            BTNode* temp = x;
            if (x->left == NULL){
                x = x->right;
            }
            else if (x->right == NULL){
                x = x->left;
            }
            else {
                replaceParent(temp, temp->left);
            }
            delete temp;
            return true;
        }
    }
}

BinarySearchTree.h

#pragma once
#include <cstddef>
using namespace std;

#ifndef BTNODE_H
#define BTNODE_H

struct BTNode{
    // Data Fields
    int data;
    BTNode* left;
    BTNode* right;

    // Constructor
    BTNode(const int& the_data,
        BTNode* left_val = NULL,
        BTNode* right_val = NULL) :
        data(the_data), left(left_val), right(right_val) {}

    // Destructor (to avoid warning message)
    ~BTNode() {
        if (this->left){
            delete this->left;
        }
        if (this->right){
            delete this->right;
        }
    }
};
#endif

#ifndef BINARY_SEARCH_TREE_H
#define BINARY_SEARCH_TREE_H

class BinarySearchTree
{
private:
    BTNode* root;

public:

    // BST Constructor / Deconstructor
    BinarySearchTree() : root(NULL){}

    BinarySearchTree(const int& the_data,
        const BinarySearchTree& left_child = BinarySearchTree(),
        const BinarySearchTree& right_child = BinarySearchTree()) :
        root(new BTNode(the_data, left_child.root, right_child.root)){}

    virtual ~BinarySearchTree(){}

    // Interface Functions ----------------------
    bool add(int data);
    bool remove(int data);
    void clear();

    // My Functions -----------------------------
    bool addRec(BTNode* &x, int data);
    bool removeRec(BTNode* &x, int data);
    bool Search(BTNode* root, int data);
    void replaceParent(BTNode* &old_root, BTNode* &local_root);
};
#endif

BinarySearchTree.cpp:

#pragma once
#include "BinarySearchTree.h"
#include <memory>
#include <thread>
#include <chrono>
#include <mutex>

// Interface Functions ----------------------
bool BinarySearchTree::add(int data){
    return addRec(root, data);
}

bool BinarySearchTree::addRec(BTNode* &x, int data){
    if (x == NULL){
        x = new BTNode(data);
        return true;
    }
    if (data == x->data){
        return false;
    }
    if (x != NULL){
        if (data < x->data){
            return addRec(x->left, data);
        }
        if (data > x->data){
            return addRec(x->right, data);
        }
    }
}

bool BinarySearchTree::remove(int data){
    return removeRec(root, data);
}

bool BinarySearchTree::removeRec(BTNode* &x, int data){
    if (x == NULL){
        return false;
    }
    else {
        if (data < x->data){
            return removeRec(x->left, data);
        }
        else if (data > x->data){
            return removeRec(x->right, data);
        }
        else // Found item
        {
            BTNode* temp = x;
            if (x->left == NULL){
                x = x->right;
            }
            else if (x->right == NULL){
                x = x->left;
            }
            else {
                replaceParent(temp, temp->left);
            }
            delete temp;
            return true;
        }
    }
}

void BinarySearchTree::replaceParent(BTNode* &old_root, BTNode* &local_root){
    if (local_root->right == NULL){
        replaceParent(old_root, local_root->right);
    }
    else{
        old_root->data = local_root->data;
        old_root = local_root;
        local_root = local_root->left;
    }
}

void BinarySearchTree::clear(){
    delete root;
    root = NULL;
}

// My Functions -----------------------------
bool BinarySearchTree::Search(BTNode* root, int data) {
    if (root == NULL) {
        return false;
    }
    else if (root->data == data) {
        return true;
    }
    else if (data < root->data) { // had <= instead
        return Search(root->left, data);
    }
    else if (data > root->data) { // had no "if"
        return Search(root->right, data);
    }
}

Main.cpp

#include <stdio.h>
#include "BinarySearchTree.h"

using namespace std;

int main(){
    BinarySearchTree myTree;

    myTree.add(6);
    myTree.add(4);
    myTree.add(8);
    myTree.add(2);

    myTree.remove(4);
}

【问题讨论】:

    标签: c++ pointers memory-management binary-search-tree


    【解决方案1】:

    当一个节点从你的树中移除时,你重新分配指向它的节点现在指向一个子节点。在这种情况下,它从6-&gt;4-&gt;2 变为6-&gt;2。但是,当您删除节点4 时,它仍然指向2。然后4 的析构函数杀死节点2

    解决方案是在删除节点之前将节点中的leftright 指针设置为NULL

    【讨论】:

    • 有趣——我突然想到要这样做,因为这似乎合乎逻辑,但在我的代码所基于的所有示例中,他们不需要分配 left 和 @ 987654331@ 到 null 在删除之前...所以我认为其他地方有问题。干杯!~
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-29
    • 1970-01-01
    • 1970-01-01
    • 2020-03-18
    相关资源
    最近更新 更多