Reputation: 53
it seems to me that I may be overlooking something in my code but please help me see it. Whenever I call this function to insert a new node, it keeps on overriding the most recent node.
node_t *node_insert(node_t *cur, char name[]){
int diff = -1;
if(cur == NULL) {
node_t *new_node = (node_t*)malloc(sizeof(node_t));
strcpy(new_node->name, name); // copy data
new_node->right = new_node->left = NULL;
return new_node; `
} else {
diff = strcmp(name, cur->name);
if(diff<0){
return node_insert(cur->left,name );}
else if(diff>0){
return node_insert (cur->right,name );}
else if (diff ==0) {
return NULL;
}
}
}
The function above is then called down below as such:
int bst_insert(bst_t *tree, char name[]){
node_t *result = node_insert(tree->root, name); // update node
if(result == NULL) { // duplicate found, ignore
return 0; // 0 indicates not modified
} else {
tree->root = result;
tree->size++; // size now larger
return 1; // 1 indicates modifed
}
}
Upvotes: 1
Views: 98
Reputation: 13570
Like I said in the comments, tree->root = result;
is correct only when tree->root
is NULL
, that means when the tree is empty. After that you've constantly updating the root node with the new node, thus forgetting the old tree.
Your node_insert
function creates a new node_t
object, that's OK. Then you do
the recursion, you find the spot where you would have to insert the new node,
but you just return the new node without adding. The information where to
add the new node is lost.
You only have to modify your node_insert
a little bit:
int node_insert(node_t **cur, char name[]) {
int diff = -1;
if(*cur == NULL) {
node_t *new_node = calloc(1, sizeof *new_node);
if(new_node == NULL)
return 0;
strcpy(new_node->name, name);
*cur = new_node;
return 1;
} else {
diff = strcmp(name, (*cur)->name);
if(diff<0){
return node_insert2(&((*cur)->left),name);}
else if(diff>0){
return node_insert2(&((*cur)->right),name);}
else if (diff ==0) {
return 0;
}
}
}
Now you have to pass a double pointer to a node_t
object. If *cur
is NULL
,
then you create a new node_t
object and assign it to *cur
, thus changing the
location (to the newly created object) where the original pointer was pointing to.
In the recursion it is only a matter of passing a pointer to the left
pointer and right
pointer. If the
recursion finds the right node and left
(or right
depending on the value of
diff
), then you pass a pointer to the pointer to the next recursion, where *cur
will be NULL
and the new node will be appended to.
Bear in mind that the way you create a new bst_t
tree is important,
tree->root
must be initialized with NULL
, otherwise the node_insert
function will fail with undefined behaviour when it is doing the recursion.
Note how I create a new node. I use calloc
because it initialized the new
memory to 0, thus new_node->left
and new_node->right
will point to NULL
.
There is one thing I don't like about your creation of a new node though:
strcpy(new_node->name, name);
Since we haven't seen how you declared the structs, it's difficult to know if
that's correct. If node_t->name
is a char*
, then you would need to allocate
memory for that and then do strcpy
:
new_node->name = calloc(strlen(name) + 1, 1);
if(new_node->name == NULL)
{
free(new_node);
return 0;
}
strcpy(new_node->name, name);
or if your system has strdup
new_node->name = strdup(name);
if(new_node->name == NULL)
{
free(new_node);
return 0;
}
But if node_t->name
is a char[SOME_LENGTH]
, the strcpy
is not the right
choice, because you have no guarantee that the string in name
is shorter than
SOME_LENGTH - 1
. In this case you would have to use strncpy
and make sure
that you end up with a valid string:
strncpy(new_node->name, name, sizeof new_node->name);
new_node->name[sizeof(new_node->name) - 1] = 0;
And of course you don't have to forget to free the memory you've allocated.
Now you can update your bst_insert
to:
int bst_insert(bst_t *tree, char name[]){
int ret = node_insert(tree->root, name);
if(ret)
tree->size++;
return ret;
}
Upvotes: 1