简体   繁体   中英

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. Neither the word nor the definition may be NULL. NULL is considered as a special value. 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? 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. 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). You should change the definition to:

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

Accordingly you should modify all accesses of tree inside your insertWord function.

Alternative working code — given a clean bill of health by 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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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