【问题标题】:Binary search tree node deletion二叉搜索树节点删除
【发布时间】:2012-11-05 08:42:46
【问题描述】:

我正在实现一个从二叉搜索树中删除节点的功能。 函数的原型已经设置好了,我也改不了了,是学校作业。 我的代码:

typedef struct tBSTNode {
    char Key;                                                                 
    struct tBSTNode * LPtr;                                
    struct tBSTNode * RPtr;  
} *tBSTNodePtr; 

void BSTDelete (tBSTNodePtr *RootPtr, char K) {
  tBSTNodePtr *tmp;

  if (*RootPtr != NULL) {
    if (K < (*RootPtr)->Key)
        BSTDelete(&(* RootPtr)->LPtr, K);
    else if (K > (*RootPtr)->Key)
        BSTDelete(&(* RootPtr)->RPtr, K);
    else {
            if ((* RootPtr)->LPtr == NULL) {
                /* there is only right branch or none*/
                tmp = RootPtr;
                *RootPtr = (* RootPtr)->RPtr;
                free(*tmp);
                *tmp = NULL;
            }
            else if ((* RootPtr)->RPtr == NULL) {
                /* there is only left branch or none*/
                tmp = RootPtr;
                *RootPtr = (* RootPtr)->LPtr;
                free(*tmp);
                *tmp = NULL;
            }
            else
                /* there are both branches, but that is for another topic*/
        }
    }
}  

此代码可以正常工作,以防没有分支连接到我要删除的节点。我预计 *tmp = NULL; 行存在问题,并且我将地址丢失到分支的其余部分,但另一方面,如果不包含此行,我将获得 SEGFAULT我正试图找出原因。

编辑:

好的,现在我知道错误在哪里了。这是愚蠢的错误,我应该使用 tBSTNodePtr tmp; 而不是 tBSTNodePtr *tmp;

【问题讨论】:

    标签: c binary-search-tree nodes


    【解决方案1】:

    您在使用指针时遇到问题。如果我们有sometype *ptr 并且我们检查这个ptr 是否涉及我们写(ptr!=NULL) 的一些空间。 *ptr 指的是值本身,例如您的结构。 阅读有关 C 中指针类型的更多信息。

    【讨论】:

    • 是的,我知道在 C 中使用指针的概念,我正在使用它,如您所见。但是指针逻辑存在问题,您的回答没有清除任何内容
    • 哦,对不起。我没有注意到 typedef 中的“*”。
    • 我想我发现了。这是错误的逻辑。如果既没有左孩子也没有右孩子,你输入两个 if 并释放一些东西两次。下面说的很对,是问题的关键。但我想你应该在条件中添加 `&& (* RootPtr)->otherside != NULL',这样你的程序才能更正确地工作。
    【解决方案2】:

    你的删除逻辑是错误的

     if ((* RootPtr)->LPtr == NULL) {
                    /* there is only right branch or none*/
                    tmp = RootPtr;
                    *RootPtr = (* RootPtr)->RPtr;
                    free(*tmp);
                    *tmp = NULL;
                }
    

    在此代码中,您将删除所需的节点,但不添加该节点的子根

     if ((* RootPtr)->LPtr == NULL) {
                    /* there is only right branch or none*/
                    tmp = RootPtr;
                    *RootPtr = (* RootPtr)->RPtr;
                    free(*tmp);
                    *tmp = NULL;
                    insert(RootPtr);  //insert the child node again in the tree
                }
    

    【讨论】:

    • 不幸的是,我不允许调用其他函数,如 insert(),所以我只需要使用我显示的代码
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-11
    • 1970-01-01
    相关资源
    最近更新 更多