难以为二叉树标记化

时间:2015-04-28 06:26:35

标签: c binary-tree tokenize

我正在尝试对文本文件进行标记,然后将标记放在二叉树中,其中具有较低值的标记位于树的左侧分支上,具有较高值的​​标记位于右侧并且重复值有更新的计数。我遇到的问题是每当" fgets"从文本文件中获取一个新的字符串行,它将二叉树的顶部更改为新字符串的第一个标记。它基本上创建了一个新的二叉树,而不是继续使用我想要的原始二叉树。我相信这些问题在于我对文本文件进行标记的方式。

功能"插入"完成二叉树的所有计算。 功能" addNode"将文本文件的第一个标记添加到二叉树的顶部。

示例文本文件:

二七八八十。

九五零

8

十分之一

    int main(void)
    {
        char buffer[100];
        char *del = " ";
        char *token;
        struct node* root = NULL;
        int i = 0;

        while (fgets(buffer, sizeof(buffer), stdin) != NULL)
        {
            token = strtok(buffer, del);

            if(root == NULL)
            {   
                printf("add: %s\n", token);
                root = addNode(token);    
            }

            else
            {
                insert(root, token);
            }


            while(token != NULL)
            {   
                token = strtok(NULL, del);

                if(token != NULL)
                    insert(root, token);
            }

        }

    }

void insert(struct node* root, char *token)
{


    if(strcmp(token, root->word) < 0)
    {
        printf("%s\n", root->word);
        if(root->left == NULL)
        {
            root->left = addNode(token);
            printf("left add: %s\n", token);

        }

        else
        {
            printf("going left\n");
            insert(root->left, token);
        }
    }

    else if(strcmp(token, root->word) > 0)
    {
        if(root->right == NULL)
        {
            root->right = addNode(token);
            printf("right add: %s\n", token);
        }
        else
        {
            printf("going right\n");
            insert(root->right, token);
        }
    }
    else
    {
        printf("updating count: %s\n", token);
        root->count = root->count + 1;
    }
}

struct node* addNode(char *token)
{
    struct node* temp = malloc(sizeof(struct node));

    temp->word = token;
    temp->left = NULL;
    temp->right = NULL;

    return temp;
}

3 个答案:

答案 0 :(得分:0)

这里的问题是变量root作为值而不是引用传递给函数insert。作为一个价值,它无法修改。

修正:

 void insert(struct node **_root, char *token)
 {
      struct node *root = *_root; /* ADDED */
      if(strcmp(token, root->word) < 0)
      {
         printf("%s\n", root->word);
         if(root->left == NULL)
         {
            root->left = addNode(token);
            printf("left add: %s\n", token);
         }
         else
         {
            printf("going left\n");
            insert(&root->left, token);    // MODIFIED
         }
     }
    else if(strcmp(token, root->word) > 0)
    {
         if(root->right == NULL)
         {
             root->right = addNode(token);
             printf("right add: %s\n", token);
         } 
         else
         {
             printf("going right\n");
             insert(&root->right, token);    // MODIFIED
         }
     }
     else
     { 
         printf("updating count: %s\n", token);
         root->count = root->count + 1;
     }
     *_root = root;
 }

 insert(&root, token);

答案 1 :(得分:0)

编写insert函数的最简单方法(以多次覆盖子指针为代价)可能是:

    struct node* insert(struct node* nd, const char* token)
    {
        int cmp;

        if(nd == NULL)
        {
            printf("add: %s\n", token);
            return addNode(token);
        }

        cmp = strcmp(token, nd->word);
        if(cmp < 0)
            nd->left = insert(nd->left, token);
        else if(cmp > 0)
            nd->right = insert(nd->right, token);
        else
        {
            printf("updating count: %s\n", token);
            nd->count ++;
        }

        return nd;
    }

然后在main

    while (fgets(buffer, sizeof(buffer), stdin) != NULL)
    {
        for( token = strtok(buffer, del); token != NULL;
            token = strtok(NULL, del))
        {   
            root = insert(root, token);
        }
    }

答案 2 :(得分:0)

程序正确率为90%。这是你的问题:

  • strtok()使用一些静态缓冲区。它将始终返回指向同一内存区域的指针。这就是为什么您觉得您的顶级节点每次都在变化。只需复制已解析的字符串。
  • 你忘了初始化每个节点的数量!你迟早会遇到麻烦,除非你也解决了这个问题。

    struct node* addNode(char *token)
    {
        struct node* temp = malloc(sizeof(struct node));
    
        temp->word = strdup(token);
        temp->left = NULL;
        temp->right = NULL;
        temp->count = 0;
    
        return temp;
    }