二叉搜索树中的搜索功能导致seg故障

时间:2014-11-23 07:37:07

标签: c string search segmentation-fault binary-search-tree

我一直试图让这个BST在最近几天工作,而我却陷入了搜索功能。逻辑似乎是正确的(除非我缺少非常重要的细节)但代码仍然有问题。可能是因为我正在处理字符串?无论如何,这里有一些代码:

编辑:我已经找到了似乎出错的地方。事实证明我的根始终为空。我放置了一个 printf 来测试NULL-case是否为true,并且它总是打印为true。我在这个问题的底部添加了我的树初始化。

(更新的)搜索功能:

//Thank you, M Oehm
node* search(node * tree, char *key)
{
    /* char *key is user input */
    int cmp;

    if(tree == NULL) {
        return NULL;
    }

    cmp = strcmp(key, tree->key);   
    if(cmp < 0) return search(tree->left, key);   
    if(cmp > 0) return search(tree->right, key);
    return tree;
}

主要功能的实施:

printf("Enter a string to search the tree with: ");
fgets(findNode, MAX_WORD, stdin);
findString = malloc(sizeof(char)*strlen(findNode)+1);
strcpy(findString,findNode);
printf("findString: %s\n", findString);
searched = search(&root, findString);
if(searched == NULL) {
    printf("No_such_key\n");
    free(findString);
    }
else {
    printNode(searched);
    free(findString);
    }
break;

树初始化(通过文件解析):

 /* Loop through each line in the file*/
 while(fgets(buffer, sizeof(buffer), file) != NULL) {
     tempToken = strtok(buffer, " \n");
     while(tempToken != NULL) {
         /* Assign default values */
         curr = (node *)malloc(sizeof(node));
         curr->left = curr->right = NULL;
         curr->key = malloc(sizeof(char)*strlen(tempToken)+1); /* +1 for '\0' */
         strcpy(curr->key, tempToken);
         curr->frequency = 1;           
         /* Insert node into tree */
         insert(&root, curr);
         /* Get next token */
         tempToken = strtok(NULL, " \n");
     }
 }
 /* Test insertion worked; close file */
 print_inorder(root);
 fclose(file);

插入功能:

void insert(node ** tree, node * item)
{
    /* If no root, item is root */
    if(!(*tree)) {
        *tree = item;
        return;
    }
    /* If item value is less than node in tree, assign to left */
    if(strcmp(item->key,(*tree)->key) < 0) {
        insert(&(*tree)->left, item);
    }
    else if(strcmp(item->key,(*tree)->key) > 0) {
        insert(&(*tree)->right, item);
    }
    else if(strcmp(item->key,(*tree)->key) == 0) {
        (*tree)->frequency++;
    }
}

打印功能向我显示插入功能正常。

3 个答案:

答案 0 :(得分:2)

您的代码中有两个错误:您不会检查传递指针的根节点是否为空,并且您不会从递归函数返回结果。

您的功能不会修改树,因此您不必将指针传递给节点。该方法对于修改树的函数很有用,例如用于插入或删除节点。您的函数应传递指向根节点的指针。这也向用户发出信号,表明该树不会被修改。

所以这是一个更正版本:

node* search(node *tree, const char *key)
{
    int cmp;

    if (tree == NULL) return NULL;

    cmp = strcmp(key, tree->key);

    if (cmp < 0) return search(tree->left, key);
    if (cmp > 0) return search(tree->right, key);
    return tree;
}

必须像这样调用该版本:

node *hit = search(tree, "bingo!");

请注意,此函数仅执行一次字符串比较,并将结果保存在临时变量中。您的代码最多会调用strcmp三次。

你不必在这里使用递归。它甚至有点浪费,因为你必须在第一次通话时渗透答案。当每个步骤都必须维护一个可以表示为局部变量的状态时,递归很有用。在这里,您只需更改输入node

这是search函数的非递归变体:

node* search(node *tree, const char *key)
{
    while (tree) {
        int cmp = strcmp(key, tree->key);

        if (cmp == 0) return tree;
        tree = (cmp < 0) ? tree->left : tree->right;
    }
    return NULL;
}

答案 1 :(得分:1)

search(&(*tree)->left, key);

应该是:

return search(&(*tree)->left, key);

相同的情况。

答案 2 :(得分:1)

尝试将您的功能更改为此类功能。

node* search(node * tree, char * key)
{
    if(tree == NULL) {
        return NULL;
    }

    if(strcmp(key,tree->key) < 0) {
        return search(tree->left, key);
    }

    else if(strcmp(key,tree->key) > 0) {
        return search(tree->right, key);
    }


    printf("Success!\n");
    return tree;

}

一个简单的节点*就足以解决您的问题了。不需要双指针。