c BST中的分段故障(核心转储)

时间:2014-07-08 11:11:30

标签: c segmentation-fault binary-search-tree

这里我已经制作了一个删除二进制搜索树(BST)的程序,但是在执行时遇到了分段错误(核心转储),我认为它在删除功能中但我不知道我是否在删除函数调用删除函数然后它工作正常,如找到最大元素,inorder遍历,但删除不会工作。

#include<stdio.h>
#include<stdlib.h>
struct BST{
    int data;
    struct BST *left;
    struct BST *right;
};
struct BST *newNode(int data){
    struct BST *temp = (struct BST *)malloc(sizeof(struct BST));
    temp->data=data;
    temp->left=0;
    temp->right=0;
    return temp;
}
void inOrder(struct BST *root){
    if(root==0)
        return;
    inOrder(root->left);
    printf("%d",root->data);
    inOrder(root->right);
}
struct BST *findMax(struct BST *root){
    if(root==0)
        return 0;
    if(root->right!=0)
        return findMax(root->right);
    return root;
}
struct BST *dele(struct BST *root,int data){
    if(root==0)
        return 0;
    if(data<root->data)
        root->left=dele(root->left,data);
    if(data>root->data)
        root->right=dele(root->right,data);
    else{
        if(root->left && root->right)
        {
            struct BST *temp=findMax(root->left);
            root->data=temp->data;
            root->left=dele(root->left,root->data);
        }
        else{
            struct BST *temp=root;
            if(root->left==0)
                root=root->right;
            if(root->right==0)
                root=root->left;
            free(temp);
            return root;
        }
    }
    return root;
}
void main(){
    struct BST *root = (struct BST*)malloc(sizeof(struct BST));
    root=newNode(1);
    root->left=newNode(2);
    root->right=newNode(3);
    root->left->left= newNode(4);
    root->left->right=newNode(5);
    root->right->left=newNode(6);
    root->right->right=newNode(7);
    inOrder(root);
    root=dele(root,1);
    printf("\n\n");
    inOrder(root);
}

3 个答案:

答案 0 :(得分:5)

void main(){
请转到:

int main(void) {

并使用NULL代替0来比较指针

我的调试器告诉我:

  

编程接收信号SIGSEGV,分段故障。   在demo.c中的0x00000000004007f0(root = 0x0,data = 5):47 47   如果(根 - &GT;右== 0)

调试步骤(使用gdb):

  • 使用-g标志进行编译:

    gcc -std = c99 -pedantic -Wall -Wextra -W -g -o demo demo.c

  • 启动gdb:

    gdb demo

  • 类型:

    运行

答案 1 :(得分:2)

罪魁祸首是

        if(root->left==0)
            root=root->right;
        if(root->right==0)
            root=root->left;

考虑leftright分支都为NULL的情况。然后第一个if(测试left是否为NULL,这是)将NULL(right)分配给root。然后是下一个if并尝试取消引用NULL指针(root->)。

我认为以下内容将纠正此错误

        if(root->left==0)
            root=root->right;
        else if(root->right==0)
            root=root->left;

或者:( 编辑:不,无论如何都不会有效,因为新的right可能是非空的

        if(root->left != NULL)
            root=root->left;
        if(root->right != NULL)
            root=root->right;

(请注意,在这种情况下,leftright不能同时为非NULL,因为此案例之前已处理过,因此此处没有内存泄漏。)

答案 2 :(得分:1)

自己更正了,其他部分的删除功能问题

else if(root->data==data){
        if(root->left && root->right)
        {
            struct BST *temp=findMax(root->left);
            root->data=temp->data;
            root->left=dele1(root->left,root->data);
        }
        else{
            struct BST *temp=root;
            if(root->left==0)
                root=root->right;
            else if(root->right==0)
                root=root->left;
            free(temp);
            return root;
        }
    }

并且我输入的节点值不表示BST,而是表示二叉树。所以,也改变了它。

root=newNode(5);
    root->left=newNode(3);
    root->right=newNode(7);
    root->left->left= newNode(1);
    root->left->right=newNode(4);
    root->right->left=newNode(6);
    root->right->right=newNode(8);

通过

恢复了分段错误
else if(root->right==0

和@Alter我们既可以使用0也可以使用NULL,并按照你的说法更改

if (root->left==0)
        root=root->right;
    if (root->right==0)
        root=root->left;

这是正确的,而不是第二个'if'我应该使用'else if'。 但感谢您对我的问题感兴趣。