在C中删除BST节点时出现堆栈溢出错误

时间:2017-10-02 03:01:54

标签: c pointers binary-search-tree nodes

我目前遇到了一个我似乎无法弄清楚的问题。目标是尝试从二叉搜索树中删除节点。出于某种原因,由于此功能,我一直遇到堆栈溢出。有什么东西我不见了吗?

int delete(struct node * n,int value) {
//if there is no bst 
if (n == NULL || head == NULL) {
    return 0;
}

//if head node is the node that has to be deleted
if (head->value == value) {
    if (head->left != NULL && head->right == NULL) {
        head = head->left;
    } else if (head->left == NULL && head->right != NULL) {
        head = head->right;
    } else if (head->left != NULL && head->right != NULL) {
        int temp = leftOfRight(head);
        head->value = temp;
        delete(head->right,temp);
    } else {
        head = NULL;
    }
}

if (n->left != NULL && n->left->value == value) { //if left node is the one that has to be deleted
    if (n->left->left != NULL && n->left->right != NULL) {
        int temp = leftOfRight(n->left);
        n->value = temp;
        delete(n->right,temp);
    } else if (n->left->left != NULL) {
        n->left = n->left->left;
    } else if (n->left->right != NULL) {
        n->right = n->right->right;
    } else {
        n->left = NULL;
    }
} else if (n->right != NULL && n->right->value == value) {
    if (n->right->left != NULL && n->right->right != NULL) { //if right node is that one that has to be deleted
        int temp = leftOfRight(n->right);
        n->value = temp;
        delete(n->right,temp);
    } else if (n->right->left != NULL) {
        n->right = n->right->left;
    } else if (n->right->right != NULL) {
        n->right = n->right->right;
    } else {
        n->right = NULL;
    }
} else if (value < n->value) {
    return delete(n->left,value);
} else if (value > n->value) {
    return delete(n->right,value);
}
return 1; }

1 个答案:

答案 0 :(得分:2)

主要问题是您在调用nullptr后没有将指针设置为delete。这导致未定义的行为。

让我演示一下:

//Create ptr & set to nullptr
Node* p_node = nullptr;
std::cout << "ptr: " << p_node << std::endl;

//Create new node on heap and point to it
Node* n = new Node(11);
p_node = n;
std::cout << "ptr: " << p_node << " node val: " << p_node->value << std::endl;

//Delete pointed-to object 
delete p_node;
std::cout << "ptr: " << p_node << " node val: " << p_node->value << std::endl;

//Set both ptrs back to nullptr
p_node = nullptr;
n = nullptr;
std::cout << "ptr: " << p_node << std::endl;

输出:

ptr: 0
ptr: 0x8c7de0 node val: 11
ptr: 0x8c7de0 node val: 3504064
ptr: 0

Delete不会删除指针,但会调用指向对象的析构函数并释放内存。在此之后我们将访问随机内存。

其他几点:

  • 很难知道整个上下文,但是遍历树的方法似乎有点令人困惑。大多数BST实现使用带有Node* current的while循环,用于递归遍历列表,直到它落在要删除的值上,或者变为nullptr - while (current != nullptr) ... if (current->value == value) break;然后检查节点是否为0, 1或2个孩子 - 并采取相应行动。这种方式阅读起来要简单得多。如果你想抽象它,你可以编写一个find_node函数,它只是将ptr返回给找到的节点。
  • Use nullptr而不是NULL。