简体   繁体   English

将单词插入二叉搜索树C

[英]Insert a word into a binary search tree C

I'm trying to build a binary search tree , that store word/definition pairs. 我正在尝试建立一个存储词/定义对的二进制搜索树。

so my struct is like this : 所以我的结构是这样的:

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

So I've been blocked in insertWord function that inserts a word/definition pair in a binary search tree. 因此,我一直在insertWord函数中受阻,该函数在二进制搜索树中插入一个单词/定义对。 Neither the word nor the definition may be NULL. 该单词或定义都不能为NULL。 NULL is considered as a special value. NULL被视为特殊值。 If the word already exists then this function replaces the current definition by the new one and returns the old one. 如果单词已经存在,则此函数将新定义替换当前定义,并返回旧定义。

This is the function: 这是功能:

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);

    }
}

What is the problem? 问题是什么?


Edited : the correct function: 编辑 :正确的功能:

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);
    }
}

So, you are trying to initialize the pointer to root of your SearchTree, the first time it's accessed, right? 因此,您正在尝试初始化首次访问SearchTree根目录的指针,对吗? The problem is that you are modifying a local copy of the pointer *tree and not the actual pointer that's present in the parent (calling) function. 问题是您正在修改指针*tree的本地副本,而不是父(调用)函数中存在的实际指针。 If you plan to modify the pointer to your SearchTree inside the called function, you should pass a pointer to the *tree in call to insertWord (ie a pointer to pointer). 如果您打算修改指针到您SearchTree调用函数里面,你应该通过一个指针*tree中调用insertWord (即以指针的指针)。 You should change the definition to: 您应该将定义更改为:

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

Accordingly you should modify all accesses of tree inside your insertWord function. 因此,您应该在insertWord函数中修改对tree所有访问。

Alternative working code — given a clean bill of health by valgrind : 备用工作代码valgrind给出了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);
}

This version reports the new definition of the word. 此版本报告了该词的新定义。 The original code may have been reporting the old definition; 原始代码可能一直在报告旧定义; it is not hard to fix this code so that it reports the old definition (but it requires a modicum of care to ensure that the old definition is actually released, and null pointers aren't printed). 修复此代码以报告旧定义并不难(但需要采取一定的谨慎措施,以确保实际上释放了旧定义,并且不打印空指针)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM