Search code examples
cbinary-search-treeuser-input

Insert Node into BST on a loop in C


I'm trying to insert into my BST but I'm struggling with creating a loop out of it. The code works when I insert one by one, but when I try to put it into a loop it doesn't insert correctly.

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h> // for strcmp()
#include <ctype.h> // for toupper()

typedef struct BstNode{
  //char name[20];
  // int data;
  struct BstNode* left;
  struct BstNode* right;
  char* name;
}BstNode;

typedef int (*Compare)(const char*, const char*); // makes comparisons easier

/* Returns pointer address to newly created node */
BstNode* createNode(char* name){ 
  BstNode* newNode = (BstNode*)malloc(sizeof(BstNode)); // Allocates memory for the newNode
  newNode->name = name; // newNode->data is like newNode.data
  newNode->left= NULL;
  newNode->right = NULL;
  return newNode;
}

//insert node into Tree recursively
BstNode* insertNode(BstNode* node, char* name, Compare cmp){
  int i;
  /* char *s1 = node->name;
     char *s2 = name;
     printf("s1: %s, s2: %s\n", s1,s2);
     i = strcmp(s1, s2); // if =1, s1 is greater
     printf("i: %d\n", i); */

  if(node == NULL){// if tree is empty
    // printf("inside NULL\n");
    node = createNode(name);
    //return node;
  }
  else{
    i = cmp (name, node->name); // sweet
    if(i == -1){
      // printf("inside left\n");
      node->left = insertNode(node->left, name, cmp);
      //return node;
    }
    else if(i == 1){
      // printf("inside right\n");
      node->right =  insertNode(node->right, name, cmp);
      //return node;
    }
    else if(i == 0 ){ //avoid duplicates for now
      // printf("inside 0\n");
      printf("Name is in BST\n");
      return NULL;
    }
  }
  return node;
}

BstNode* printTree(BstNode* node){
  if(node == NULL){
    return NULL;
  }
  printTree(node->left);
  printf("%s\n",node->name);
  printTree(node->right);
}

int CmpStr(const char* a, const char* b){
  return (strcmp (a, b));     // string comparison instead of pointer comparison
}
//void Insert(Person *root, char name[20]);

int main(){
  BstNode* root = NULL; // pointer to the root of the tree
  char buf[100];
  char option = 'a';

  while(1) { 
    printf("Enter employee name");
    scanf("%s",buf); 
    printf ("Inserting %s\n", buf);
    root =  insertNode(root, buf, (Compare)CmpStr);
    printTree(root);
  }
}

I can do root = insertNode(root, name, (Compare)CmpStr) several times in code, but if I try to loop it with user input it won't insert correctly. I'm not sure if it has to do with the fact that I'm using scanf() or root not being set correctly. I've tried using fgets() as well but I'm not too sure how to use it and keep messing that up. Any help is appreciated.


Solution

  • In your loop, you always pass the same buffer to your insert function; Your createNode does not copy the content of the buffer but rather stores a reference to the (always) same buffer; Hence, changing the buffer content after insert will also change the "content" of previously inserted nodes.

    I'd suggest to replace newNode->name = name in createNode with newNode->name = strdup(name). This will actually copy the passed "contents" and gives your BST control over the memory to be kept. Thereby don't forget to free this memory when deleting nodes later on.