node_t *insert_node(node_t *root, node_t *new) {
node_t *curr;
curr = root;
if(root == NULL) {
root = new;
return root;
} else {
while(curr) {
printf("%s", curr->name);
if(strcmp(curr->name, new->name)<0) {
curr = root->left;
} else {
curr = root->right;
}
}
printf("%s", curr);
curr = new;
printf("%s\n", curr->name);
} `enter code here`
return root;
}
tree_t *insert_tree(tree_t *tree, void *line1, void *line2){
node_t *new;
new = malloc(sizeof(*new));
new->name = line1;
new->movie = line2;
new->left = new->right = NULL;
tree->root = recursive_insert(tree->root, new);
return tree;
}
static node_t *recursive_insert(node_t *root, node_t *new) {
if(root==NULL){
return new;
} else if((strcmp(root->name, new->name))<0) {
root->left = recursive_insert(root->left, new);
} else {
root->right = recursive_insert(root->right, new);
}
return root;
}
过去50个小时左右我一直在研究这个问题,只是为了让它发挥作用。
问题似乎出现在while
声明的if
循环中。
curr = root-> left;
和curr = root->right
未按预期正确更新节点。
检查它是否确实更新我在printf
循环中插入了while
语句。
它打印出同样的东西。
这使得strcmp
一遍又一遍地比较具有相同字符串的字符串。
我认为这可能与结构属性有关,但我不知道是什么。
底部的两个函数通过递归实现对树的插入
我一直试图用迭代插入实现递归插入
因为
当数据文件很大时,递归失败
递归工作没有任何错误
顶部函数和底部两个函数意味着做同样的事情
底部的两个工作正常
但是带有while循环的顶部没有
任何人都可以比较两个版本的错误!!
答案 0 :(得分:1)
if(strcmp(curr->name, new->name)<0) {
curr = root->left;
} else {
curr = root->right;
}
您总是分配相同的值...也许您的意思是curr = curr->left
和curr = curr->right
?
答案 1 :(得分:1)
有两个大问题。第一个是你使用root->left
和root->right
,它不会在你的树下向前移动,而是停留在根节点的子节点上。如果你的root有子节点,这将导致无限循环,如果root没有子节点,它将不会插入任何新的循环。
然而,这甚至不是还的问题,因为你没有正确插入任何东西(因此root将永远不会有子代)。您将new
分配到curr
,或许会认为这会将节点添加到树中。 curr
是一个局部变量;您有兴趣更新的指针是curr->left
和curr->right
。
当然,当您的while循环结束时,curr
为空,因此curr->left
和curr->right
甚至不存在。
所以,修复如下:
root->left
和root->right
更改为curr->left
和curr->right
。首先检查子项是否为空。如果没有,则将工作节点设置为子节点并保持循环。否则,将节点保存在树中并以某种方式退出循环。
if (curr->left) {
curr = curr->left;
} else {
curr->left = new;
return curr->left; // we return the newly inserted node immediately
}
您的递归版本有效,因为您将递归调用的结果分配到root->left
或root->right
。传入的root
节点为空时,递归函数返回新节点。所以你要将子指针分配给新节点。
此外,为了消除您对root
和curr
的混淆:在递归版本中,没有“工作”节点;也就是说,每个递归调用都在处理它自己的“root”。根不是整个树的根,但实际上子节点的根节点由父节点的左或右指针指向。在循环版本中,我们不是将子节点传递给下一个递归调用,而是将指向子节点的指针分配到“工作”节点curr
。