为什么要将项插入二叉树的迭代失败?

时间:2015-09-01 07:19:37

标签: c

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循环的顶部没有

任何人都可以比较两个版本的错误!!

2 个答案:

答案 0 :(得分:1)

if(strcmp(curr->name, new->name)<0) {           
    curr = root->left;
} else {
    curr = root->right;
}

您总是分配相同的值...也许您的意思是curr = curr->leftcurr = curr->right

答案 1 :(得分:1)

有两个大问题。第一个是你使用root->leftroot->right,它不会在你的树下向前移动,而是停留在根节点的子节点上。如果你的root有子节点,这将导致无限循环,如果root没有子节点,它将不会插入任何新的循环。

然而,这甚至不是的问题,因为你没有正确插入任何东西(因此root将永远不会有子代)。您将new分配到curr,或许会认为这会将节点添加到树中。 curr是一个局部变量;您有兴趣更新的指针是curr->leftcurr->right

当然,当您的while循环结束时,curr为空,因此curr->leftcurr->right甚至不存在。

所以,修复如下:

  1. root->leftroot->right更改为curr->leftcurr->right
  2. 首先检查子项是否为空。如果没有,则将工作节点设置为子节点并保持循环。否则,将节点保存在树中并以某种方式退出循环。

    if (curr->left) {
        curr = curr->left;
    } else {
        curr->left = new;
        return curr->left; // we return the newly inserted node immediately
    }
    
  3. 您的递归版本有效,因为您将递归调用的结果分配到root->leftroot->right。传入的root节点为空时,递归函数返回新节点。所以你要将子指针分配给新节点。

    此外,为了消除您对rootcurr的混淆:在递归版本中,没有“工作”节点;也就是说,每个递归调用都在处理它自己的“root”。根不是整个树的根,但实际上子节点的根节点由父节点的左或右指针指向。在循环版本中,我们不是将子节点传递给下一个递归调用,而是将指向子节点的指针分配到“工作”节点curr