我正在尝试构建一个存储字/定义对的二叉搜索树。
所以我的结构是这样的:
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);
}
}
答案 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);
}
此版本报告该词的新定义。原始代码可能已经报告了旧的定义;修复此代码并不难以报告旧的定义(但需要小心谨慎以确保实际发布旧定义,并且不打印空指针)。