打印二进制搜索树,出现分段错误错误11

时间:2018-09-23 11:34:29

标签: c binary-search-tree

你能帮我吗?

程序从文件中读取单词并将其放入二进制搜索树,但是运行打印功能时出现“ Segmentation fault:11”。

struct node {
    char * item;
    struct node * left;
    struct node * right;
};

struct node * new(char * a) {
    struct node * new;
    new = (struct node *)malloc(sizeof(struct node *));
    new->item = a;
    new->left = new->right = NULL;
    return new;
}

struct node * insert(struct node * a, char * b) {
    if(a == NULL) {
        a = new(b);
    }
    else if (b <= a->item) {
        a->left = insert(a->left, b);
    }
    else {
        a->right = insert(a->right, b);
    }
    return a;
}

void print(struct node * a) {
    if (a->left == NULL && a->right == NULL)
        printf("%s", a->item);
    else if (a->left != NULL)
        print(a->left);
    else
        print(a->right);
}

来自main.c:

   struct node * root = NULL;
   struct node * start;

   start = root;

   while (fscanf(fp, "%s", temp) != EOF) {
   root = insert(root, temp); // insert function works ok
   }

   print(start);

更新: 我对main.c进行了更改:

int i = 0;

while (fscanf(fp, "%s", temp) != EOF) {
        root = insert(root, temp);
        if (!i) {
            start = root;
            i = 1;
        }
    }

现在它不显示错误,但是它仅打印树中的最后一个单词,而不是递归打印。有什么建议吗?

更新#2: 谢谢您的帮助。根据您的建议,我对该功能进行了更改:

struct node * new(char * a) {
    struct node * new;
    char * stringcopy;
    stringcopy = malloc(strlen(a) + 1);
    strcpy(stringcopy, a);
    new = malloc(sizeof(* new));
    new->item = stringcopy;
    new->left = new->right = NULL;
    return new;
}

现在一切正常。

1 个答案:

答案 0 :(得分:0)

最初的问题几乎可以肯定是startNULL,因为您在更新root时没有更新它。 (与此同时,似乎不需要整个start;只需直接使用root。)

新问题(仅打印最后一个单词)是您没有正确遍历树:print函数仅在leftright均为{{1}时才打印},因此只会打印一个叶子节点,而且如果存在NULL分支,它也不会下降到right分支中。

您可以尝试使用类似的方法(未经测试的代码):

left

尤其要注意,如果您位于非void print(struct node * a) { if (a == NULL) { return; } print(a->left); (void) puts(a->item); print(a->right); } 节点上,则需要无条件打印其NULL,否则整个输出将丢失该节点。

另一个问题似乎是在创建节点时没有复制item。因此,如果您在item中的temp确实是一个临时对象,将被覆盖或释放,则您尝试执行的所有insert(root, temp)(可能最后一个除外)都将无效。打印它们。代替分配item,执行等效于new->item = a的操作,然后记住在释放节点时new->item = strdup(a)

({free不在C标准库中,但是很容易实现:为字符串分配足够的空间,包括NUL终止符并进行复制。)

此外,比较strdup几乎可以肯定没有按照您的期望进行;参见b <= a->item