[英]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.