二进制搜索树,节点删除崩溃

时间:2016-07-16 17:33:52

标签: c pointers tree binary-search-tree

我编写了二进制搜索树。每个函数都可以正常工作,但是" deletenode"。该方法应该删除* p指向的节点。

但是,如果节点是叶子,它将打印没有节点的树并崩溃。 如果节点没有叶子,它甚至不会打印树并崩溃。

我没有看到任何可能的方法在更少的代码中重新创建问题,因为我不知道问题应该在哪里。 我很抱歉

也许有人可以加载它并查看问题所在,因为我非常绝望。

#include <stdio.h>

void *malloc(size_t size);
void free(void *ptr);

struct tnode {
    int content;
    struct tnode *left; /* left subtree */
    struct tnode *right; /* right subtree */
};


struct tnode *talloc(void) /* reserves memory*/
{
    return (struct tnode *) malloc(sizeof(struct tnode));
}

struct tnode *addelement(struct tnode *p, int i)   /* addelement: adds new node */
{
    int cond;
    if(p == NULL) {
        p = talloc(); /* make a new node */ p->content = i;
        p->left = p->right = NULL;
    } else if(p->content == i) {
        return p;
    } else if(i < p->content) /* goes to the left side */ p->left = addelement(p->left, i);
    else /* goes to the right side */ p->right = addelement(p->right, i);
    return p;
}

struct tnode *addtree(struct tnode *top, struct tnode *p) /* adds subtree to main tree*/
{
    if(p == NULL)
        return top;
    else
        return addtree(addtree(addelement(top, p->content), p->right), p->left);
}

int printtree_preorder(struct tnode *p) /* prints tree in preorder*/
{
    if(p != NULL) {
        printf("%d \n", p->content);
        printtree_preorder(p->left);
        printtree_preorder(p->right);
    }
    return 0;
}

int printtree_inorder(struct tnode *p)  /* prints tree in inorder*/
{
    if(p != NULL) {
        printtree_inorder(p->left);
        printf("%d \n", p->content);
        printtree_inorder(p->right);
    }
    return 0;
}

int printtree_postorder(struct tnode *p)    /* prints tree in postorder*/
{
    if(p != NULL) {
        printtree_postorder(p->left);
        printtree_postorder(p->right);
        printf("%d \n", p->content);
    }
    return 0;
}

struct tnode *searchnode(struct tnode *p, int nodtodelete) /* pointer is set on the node which is supposed to be deleted  */
{
    if(p == NULL) {
        printf("Baum ist leer oder Element nicht vorhanden \n");
        return 0;
    }
    if(p->content == nodtodelete) {
        return p;
    }
    if(p->content < nodtodelete) {
        return searchnode(p->right, nodtodelete);
    }
    if(p->content > nodtodelete) {
        return searchnode(p->left, nodtodelete);
    }
}

struct tnode  *deletenode(struct tnode *p, struct tnode *pBaum) /* Is supposed to delete the node which the *p is pointing at */
{
    if((p->left == NULL) && (p->right == NULL)) {
        free(p);
        printf("Ist Blatt \n");
        return pBaum;
    }
    if((p->left == NULL) && (p->right != NULL)) {
        struct tnode *rechterTeilbaum = p->right;
        free(p);
        pBaum = addtree(pBaum, rechterTeilbaum);
        return pBaum;

    }
    if((p->right == NULL) && (p->left != NULL)) {
        struct tnode *linkerTeilbaum = p->left;
        free(p);
        pBaum = addtree(pBaum, linkerTeilbaum);
        return pBaum;
    }
    if((p->left != NULL) && (p->right != NULL)) {
        struct tnode *rechterTeilbaum = p->right;
        struct tnode *linkerTeilbaum = p->left;
        free(p);
        pBaum = addtree(pBaum, rechterTeilbaum);
        pBaum = addtree(pBaum, linkerTeilbaum);
        return pBaum;
    }
}

int main() {
    struct tnode *Baum = NULL;
    struct tnode *tmpPos = NULL;

    Baum = addelement(Baum, 10);
    Baum = addelement(Baum, 30);
    Baum = addelement(Baum, 20);
    Baum = addelement(Baum, 35);

    tmpPos = searchnode(Baum, 35);

    if(tmpPos != 0) {
        printf("Zu loeschendes Element: %d \n", tmpPos->content);
        Baum = deletenode(tmpPos, Baum);
    }

    printf("Inorder Ausgabe\n");
    printtree_inorder(Baum);

    printf("Postorder Ausgabe\n");
    printtree_postorder(Baum);

    printf("Preorder Ausgabe\n");
    printtree_preorder(Baum);
}

1 个答案:

答案 0 :(得分:1)

在deletenode函数中,在尝试取消引用之前,您不会检查p是否为NULL。你是segfaulting?