将单词插入二叉搜索树C.

时间:2014-12-28 17:49:46

标签: c binary-search-tree

我正在尝试构建一个存储字/定义对的二叉搜索树。

所以我的结构是这样的:

struct BinarySearchTree_t
{
    char *word,*def;
    struct BinarySearchTree_t *left;
    struct BinarySearchTree_t *right;
};
typedef struct BinarySearchTree_t BinarySearchTree;

所以我在insertWord函数中被阻塞,该函数在二叉搜索树中插入一个单词/定义对。单词和定义都不能为NULL。 NULL被视为特殊值。如果该单词已经存在,则此函数将用新的替换当前定义并返回旧定义。

这是功能:

char* insertWord(BinarySearchTree *tree, char *word, char *definition)
{
    int r;
    char* a;

    if((tree==NULL))
    {
        BinarySearchTree* tmp;
        tmp = malloc( sizeof( BinarySearchTree ) );
        tmp->word= malloc((strlen(word)+1)*sizeof(char));
        tmp->def = malloc((strlen(definition)+1)*sizeof(char));
        strcpy(tmp->word, word);
        strcpy(tmp->def , definition);
        tmp->left = NULL;
        tmp->right = NULL;

        *tree = *tmp;
        return NULL;
    }
    else
    {
        a= tree->word;
        r= strcmp(a,word);
        if(r = 0)
        {
            char* ret= tree->def;
            strcpy(tree->word, word);
            strcpy(tree->def , definition);
            return ret;
        }
        else if(r<0)
           return insertWord((tree->right),word,definition);
        else
           return insertWord((tree->left),word,definition);

    }
}

有什么问题?


已编辑:正确的功能:

char* insertWord(BinarySearchTree **tree, char *word, char *definition) 
    {                                                                   
    int r;
    char* a;

    if(((*tree)==NULL) || ((*tree)!=NULL && (*tree)->mot==NULL))
    {
        BinarySearchTree* tmp;
        tmp = malloc( sizeof( BinarySearchTree ) ); 
        tmp->left = NULL;                           
        tmp->right = NULL;                          

        tmp->mot = malloc((strlen(word)+1)*sizeof(char));
        tmp->def = malloc((strlen(definition)+1)*sizeof(char));
        strcpy(tmp->mot , word);                    
        strcpy(tmp->def , definition);              

        *tree = tmp;
        return NULL;
    }
    else
    {
        a= (*tree)->mot;
        r= strcmp(a,word);
        if(r == 0)
        {
            char* ret= (*tree)->def;
            strcpy((*tree)->mot , word);
            strcpy((*tree)->def , definition);
            return ret;
        }
        else if(r<0)
            return insertWord(&((*tree)->right),word,definition); 
        else
            return insertWord(&((*tree)->left),word,definition);
    }
}

2 个答案:

答案 0 :(得分:1)

因此,您尝试初次化指向SearchTree根目录的指针,这是第一次访问它,对吗?问题是您正在修改指针*tree的本地副本,而不是父(调用)函数中存在的实际指针。如果您计划在被调用函数内修改指向SearchTree的指针,则应该在调用*tree时向insertWord传递指针(即指向指针的指针)。 您应该将定义更改为:

  

char * insertWord(BinarySearchTree ** tree,char * word,char * definition)

因此,您应修改tree功能中insertWord的所有访问权限。

答案 1 :(得分:1)

替代工作代码 - valgrind给出了清晰的健康状况:

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

struct BinarySearchTree_t
{
    char *word, *def;
    struct BinarySearchTree_t *left;
    struct BinarySearchTree_t *right;
};
typedef struct BinarySearchTree_t BinarySearchTree;

static void freeTree(BinarySearchTree *root);
static void dump_tree(BinarySearchTree *root);
extern char *insertWord(BinarySearchTree **ptree, char *word, char *definition);

char *insertWord(BinarySearchTree **ptree, char *word, char *definition)
{
    if (*ptree == NULL)
    {
        BinarySearchTree *tmp = malloc(sizeof(*tmp));
        tmp->word = strdup(word);
        tmp->def = strdup(definition);
        tmp->left = NULL;
        tmp->right = NULL;
        *ptree = tmp;
        return tmp->def;
    }
    else
    {
        BinarySearchTree *tree = *ptree;
        int r = strcmp(tree->word, word);
        if (r == 0)
        {
            free(tree->def);
            tree->def = strdup(definition);
            return tree->def;
        }
        else if (r < 0)
            return insertWord(&tree->right, word, definition);
        else
            return insertWord(&tree->left, word, definition);
    }
}

int main(void)
{
    char *word_defs[][2] =
    {
        { "cat", "feline" },
        { "dog", "canine" },
        { "box", "carton" },
        { "cat", "purring critter" },
    };
    BinarySearchTree *root = 0;

    for (size_t i = 0; i < sizeof(word_defs) / sizeof(word_defs[0]); i++)
    {
        printf("%zu: Add %s => %s\n", i, word_defs[i][0], word_defs[i][1]);
        char *def = insertWord(&root, word_defs[i][0], word_defs[i][1]);
        dump_tree(root);
        printf("New definition: %s\n", def);
    }

    freeTree(root);

    return 0;
}

static void freeTree(BinarySearchTree *root)
{
    if (root != 0)
    {
        freeTree(root->left);
        freeTree(root->right);
        free(root->word);
        free(root->def);
        free(root);
    }
}

static void dump_tree(BinarySearchTree *root)
{
    if (root->left != 0)
        dump_tree(root->left);
    printf("%p: %s => %s\n", (void *)root, root->word, root->def);
    if (root->right != 0)
        dump_tree(root->right);
}

此版本报告该词的新定义。原始代码可能已经报告了旧的定义;修复此代码并不难以报告旧的定义(但需要小心谨慎以确保实际发布旧定义,并且不打印空指针)。