【问题标题】:BST node delete function failing at recursive callBST 节点删除函数在递归调用中失败
【发布时间】:2016-12-23 11:30:36
【问题描述】:
void search(struct node **root, struct node **cursor,
            struct node **parent, int data, int *found) {
    struct node *iterator = *root;

    *cursor = NULL, *parent = NULL;
    *found = FALSE;

    while (iterator != NULL) {
        if (data == iterator->data) {
            *found = TRUE;
            *cursor = iterator;
            break;
        } else
        if (data <= iterator->data) {
            *parent = iterator;
            iterator = iterator->left;
        } else {
            *parent = iterator;
            iterator = iterator->right;
        }
    }
}

void delete(struct node **root, int data) {
    int found;
    struct node *cursor, *parent;

    if (*root == NULL) {
        printf("ERROR! Binary Search Tree Empty!\n");
        exit(0);
    }
    search(root, &cursor, &parent, data, &found);
    if (found == FALSE) {
        printf("ERROR! Element not found in Binary Tree!\n");
        exit(0);
    }
    //  If the Node has No Children
    if (cursor->left == NULL && cursor->right == NULL) {
        if (parent->left == cursor) {
            parent->left = NULL;
        } else {
            parent->right = NULL;
        }
        free(cursor);
    }
    if (cursor->left == NULL && cursor->right != NULL) {
        if (parent->left == cursor) {
            parent->left = cursor->right;
        } else {
            parent->right = cursor->right;
        }
        free(cursor);
    }
    if (cursor->left != NULL && cursor->right == NULL) {
        if (parent->left == cursor) {
            parent->left = cursor->left;
        } else {
            parent->right = cursor->left;
        }
        free(cursor);
    }
    // If node has two children
    if (cursor->left != NULL && cursor->right != NULL) {
        struct node *iterator = cursor;
        iterator = iterator->right;
        while (iterator->left != NULL) {
            iterator = iterator->left;
        }
        cursor->data = iterator->data;
        printf("\n%i\n", iterator->data);
        delete(&iterator, iterator->data);
    }
}

我正在尝试实现二叉搜索树删除功能。我已经测试了许多 BST,但是当我删除一个有两个孩子的节点时它失败了。它在 recursive 调用中失败。它给出了分段错误 11。我该怎么办?

【问题讨论】:

  • 您的程序在对象生命周期结束后访问对象时表现出未定义的行为。
  • 对象的生命周期如何结束? 'iterator' 还在,怎么没了?
  • C11 标准草案 n1570:6.2.4 对象的存储持续时间 2 对象的生命周期是程序执行期间保证为其保留存储的部分。[... ] 34) 如果对象在其生命周期之外被引用,则行为未定义。当指针指向(或刚刚过去)的对象到达其生命周期的末尾时,指针的值变得不确定。 7.22.3 内存管理函数 1 [...] 已分配对象的生命周期从分配一直延续到释放。[...]
  • 好的,那我该如何解决这个问题呢?
  • free() 之后不要访问对象?这听起来并不复杂,是吗?

标签: c algorithm data-structures binary-tree binary-search-tree


【解决方案1】:

你的delete 函数的问题是你没有在每个free(cursor); 之后返回。相反,您继续测试下一个案例,取消引用刚刚释放的 cursor。问题主要在于cursor 有 1 个或没有孩子。

【讨论】:

  • 考虑到函数递归直到 cursor 的孩子少于两个,未定义的行为是不可避免的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-11
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 2021-04-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多