你能帮我吗?
程序从文件中读取单词并将其放入二进制搜索树,但是运行打印功能时出现“ 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;
}
现在一切正常。
答案 0 :(得分:0)
最初的问题几乎可以肯定是start
是NULL
,因为您在更新root
时没有更新它。 (与此同时,似乎不需要整个start
;只需直接使用root
。)
新问题(仅打印最后一个单词)是您没有正确遍历树:print
函数仅在left
和right
均为{{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
。