实现搜索功能后的二叉树分割故障

时间:2014-07-30 06:49:32

标签: c segmentation-fault structure binary-tree

我正在尝试编写一个将执行以下操作的程序

-read a file from std in
-read each line, and add each line to a binary tree
 *if name is already in binary tree,dont add the name to the tree again but update its count of repititions
-print out the binary tree

正在读入的文件类似于

dylan
bob
dylan
randall
randall

所以当我打印出二叉树时,我希望它打印出来

bob 1
dylan 2
randall 2

我能够成功打印出名字而不必担心重复。我已经注释掉了使我的程序混乱的代码块,这是与我的搜索功能相互作用的任何东西,我在事后处理重复。代码构建了一个二叉树,每个“leave”是一个由4个部分组成的结构,即name,thecount和指向左右孩子的指针。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct node {
    char* name;
    int count;
    struct node* left;
    struct node* right;
};

struct node* addNode(char* string);
void insert(struct node *root, char* stringgg);
void preorder(struct node *root);
int search(struct node* leaf,char* string2find);

int main()
{
    char buffer[20];
    struct node *root = NULL;

    while( fgets(buffer, sizeof(buffer), stdin) != NULL )
    {
        if(root == NULL)
            root = addNode(buffer);
        else

            insert(root,buffer);

    }
    preorder(root);

}

struct node* addNode(char* string)
{
    struct node *temp = malloc(sizeof(struct node));
    temp->name = malloc(strlen(string) + 1);
    strcpy(temp->name,string);

    temp->left = NULL;
    temp->right = NULL;
    return temp;
}

void insert(struct node *root, char* stringgg)
{
   /* int flag = 5;
    flag = search(root,stringgg);
    if(flag == 1)
        return; */

    if(strcmp(stringgg,root->name) < 0)
    {
        if(root->left == NULL)
            root->left = addNode(stringgg);
        else
            insert(root->left, stringgg);
    }
    else
    {
        if(root->right == NULL)
            root->right = addNode(stringgg);
        else
            insert(root->right,stringgg);
    }
}

/*int search(struct node* leaf,char* string2find)
{
    if(strcmp(string2find,leaf->name) == 0)
    {
        leaf->count = leaf->count + 1;
        return 1;
    }
    else if(strcmp(string2find,leaf->name) < 0)
    {
        return search(leaf->left,string2find);
    }
    else
    {
        return search(leaf->right,string2find);
    }
    return 0;

} */

void preorder(struct node *root)
{
    if(root == NULL)
        return;
    printf("%s",root->name);
    preorder(root->left);
    preorder(root->right);

}

上面的代码打印出所有名称,即使已经存在于树中。我希望有人能够指出我的搜索功能错误,以便在打印时不会导致分段错误。可能的原因可能是我不恰当地使用return函数,其中我试图返回main如果flag == 1这意味着匹配被发现所以不添加节点。但是如果flag不等于1则没有找到匹配,那么就去添加节点。

2 个答案:

答案 0 :(得分:0)

at main

while( fgets(buffer, sizeof(buffer), stdin) != NULL ){
    char *p = strchr(buffer, '\n');
    if(p) *p=0;//remove '\n'

at addNode

temp->count = 1;//initialize counter
return temp;

插入

void insert(struct node *root, char* stringgg){
    int cmp_stat = strcmp(stringgg,root->name);

    if(cmp_stat == 0)
        root->count++;
    else if(cmp_stat < 0) {
        if(root->left == NULL)
            root->left = addNode(stringgg);
        else
            insert(root->left, stringgg);
    } else {
        if(root->right == NULL)
            root->right = addNode(stringgg);
        else
            insert(root->right,stringgg);
    }
}

预购

printf("%s %d\n",root->name, root->count);

答案 1 :(得分:0)

错误在于搜索树中的第一项 - 您调用

    search(root, stringgg)

rootNULL,因此在search()中您可以调用

    strcmp(string2find, leaf->name)

leaf == NULL,程序崩溃。

治愈:不要搜索 BEFORE 更新树,而是搜索 TO 更新它。

struct node* update(struct node* nd, const char* str)
{
    int cmp;

    // (sub)tree is empty? - create a new node with cnt==1
    if(nd == NULL)
        return CreateNode(str);

    // test if the node found
    cmp = strcmp(str, nd->name);

    if(cmp == 0)          // YES
        nd->count ++;     // update the counter
    else if(cmp < 0)      // NO - search in a subtree
        nd->left  = update(nd->left,  str);
    else
        nd->right = update(nd->right, str);

    return nd;            // return the updated subtree
}

然后在main()中,您只需更新树并存储它:

    root = update(root, buffer);

实际上,root值在第一次调用时只会更改一次,并且所有后续分配都不会更改其值。然而,这使代码更具可读性。