0

I'm running into an issue with a simple binary tree manipulation program. There's a zero being entered somewhere in the code, and I simply can't figure out how to get rid of it. Here's the main function in the program:

//-------------------------Structure definition----------------------------------------------------------------------------------
struct tree {
    int data;
    struct tree *left;
    struct tree *right;
};


//-------------------------Function definitions--------------------------------------------------------------------------------
int traverse(struct tree *root);
struct tree * insert(struct tree *root, int num);
int search(struct tree *root, int num);
int maxdepth(struct tree *root);
void help();


//-------------------------Help function to display commands----------------------------------------------------------
void help()
{
    printf("\n Q to quit program. \n");
    printf(" # to insert # into the list. \n");
    printf(" s # to search for # in the list. \n");
    printf(" d # to delete # from list. \n");
    printf(" p to print the entire list. \n");
    printf(" ? to view this message again. \n\n");
}


//-------------------------Traverse (print)--------------------------------------------------------------------------------------
int traverse(struct tree *root)
{
    if(root==NULL)
    {
        return 0;
    }
    traverse(root->left);
    printf("%d ", root->data);
    traverse(root->right);
}


//-------------------------Insert function to sort and insert user input ----------------------------------------------
struct tree * insert(struct tree *root, int num)
{
    if(root==NULL)
    {
        root=malloc(sizeof(struct tree));
        root->data = num;
        root->left = root->right=NULL;
        return(root);
    }
    if(num > root->data)
    {
        root->right=insert(root->right, num);
        return(root);
    }
    if(num < root->data)
    {
        root->left=insert(root->left, num);
        return(root);
    }
    if(num==root->data)
    {
        return (root);
    }
}


//-------------------------Search function. Just returns a 1/0 for yes/no ------------------------------------------
int search(struct tree *root, int num)
{
    if(root==NULL)return(0);
    if(num==root->data)return(1);
    if(1==search(root->left, num) || 1==search(root->right, num))
    {
        return(1);
    }
    else
    {
        return(0);
    }
}


//------------------------MaxDepth function to calculate the depth of the tree --------------------------------
int maxdepth(struct tree *root)
{
    int ldepth;
    int rdepth;
    if(root==NULL)
    {
        return 0;
    }
    else
    {
        ldepth=maxdepth(root->left);
        rdepth=maxdepth(root->right);
        if(ldepth > rdepth)
            return ldepth+1;
        else
            return rdepth+1;
    }
}

//-------------------------Main! --------------------------------------------------------------------------------------------------
int main(void)
{
    struct tree *root;
    char buffer[120]; //Temp storage
    int num; //User input will move from buffer to here.
    int searchVal;

//Memory Allocations block. 
    root=malloc(sizeof(struct tree));       


    printf("Hello. \n");
    while(1==1)
    {
        printf("> ");

        fgets(buffer, sizeof(buffer), stdin);

        switch(buffer[0])
        {
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                if(1==(sscanf(buffer, "%d", &num))){
                    insert(root, num);
                    }
                break;

            case 's':
                if(1==(sscanf(buffer, "s %d", &num))){
                    searchVal=search(root, num);
                    if(1==search(root, num)){
                        printf("That number is in the list. \n");
                    }else{
                        printf("That number is not in the list. \n");
                    }
                }
                break;


            case 'p':
                traverse(root);
                printf("\n Tree depth: %d \n", maxdepth(root)); 
                break;

            case '?':
                help();
                break;

            case 'q':
            case 'Q':
                exit(0);
                break;

            default:
                help();
                break;

            }
    }
}

According to GDB, root->data is set to zero at the "printf("Hello \n") line, which doesn't make much sense to me. Any help would be appreciated, let me know if you need to see the other functions and I'll edit them in. Thanks in advance.

alldavidsluck
  • 77
  • 2
  • 3
  • 10
  • Where's your `struct tree` definition? What does `insert` do? `search`? `traverse`? We need to see all the code required to reproduce the problem, what went in, and what came out. – nmichaels Jan 27 '14 at 20:43
  • Edited to include those. – alldavidsluck Jan 27 '14 at 20:50
  • 2
    root=malloc(sizeof(struct tree)); root=NULL; ??? – Dabo Jan 27 '14 at 20:54
  • Addressed this in replies to the answers below, I was testing and forgot to take the NULL statement out. My bad. Basically without the NULL statement, printing data results in a zero being in the front and screws the depth calculation up. – alldavidsluck Jan 27 '14 at 21:05
  • `root=malloc(sizeof(struct tree));` replace with `root = NULL;` and should be `root=insert(root, num);` – BLUEPIXY Jan 27 '14 at 21:24
  • This worked, thank you. So the whole reason the zero was there is because I was allocating in main and then passing it by reference, instead of passing and then allocating? – alldavidsluck Jan 27 '14 at 21:50

3 Answers3

0

Your variable "root" is set to NULL, so it doesn't point to the element allocated at the first call of "insert".

EDIT (follow-up of the comment) The root element (the one you allocate in the "main" function is not initialized. You have to

1) initalize its elements (left and right to NULL, at least) 2) put the very first value in its "data" field.

The "0" is the field of that element.

Giuseppe Guerrini
  • 4,274
  • 17
  • 32
  • Was trying to get rid of the zero and forgot to take that NULL statement out. Even without that, there is still a zero present in the actual data. Inputting a 2,3,1 will result in an output of 0 1 2 3 and a tree depth of 3 which is incorrect. – alldavidsluck Jan 27 '14 at 20:59
0
//Memory Allocations block. 
root=malloc(sizeof(struct tree)); 
root=NULL;

Don't set to NULL after you allocate memory.

  • Addressed this in a post above as well, but I was actually trying this to see if I could get rid of the zero. Without that NULL statement, there is still a zero present in the actual data. Inputting a 2,3,1 will result in an output of 0 1 2 3 and a tree depth of 3 – alldavidsluck Jan 27 '14 at 21:01
0

Your problem is in first insert. In main function, you allocate memory for root element so in the insert function :

struct tree * insert(struct tree *root, int num)
{
    if(root==0)
    {
        root=malloc(sizeof(struct tree));
        root->data = num;
        root->left = root->right=0;
        return(root);
    }
    if(num > root->data)
    {
        root->right=insert(root->right, num);
        return(root);
    }

first if is always false, so you add new node instead of writing first element at the root.

Edit: don't allocate memory for root in main, and rewrite your insert function so it will get struct tree** root . something like that :

struct tree * insert(struct tree** root, int num)
{
        if(*root==NULL)
        {
           *root=malloc(sizeof(struct tree));
           (*root)->data = num;
           (*root)->left = (*root)->right=0;
           return(*root);
       .........

and invoke it like that

 root = NULL;
 .......
 insert(&root, num);
Dabo
  • 2,371
  • 2
  • 18
  • 26
  • This would be true after I input data. But if I just compile, run, and call traverse without calling insert at all, the zero is still there and the tree depth is 1. ` ./p3 Hello. > p 0 Tree depth: 1 >` – alldavidsluck Jan 27 '14 at 21:23
  • I can't do this due to program requirements. Function calls are required to be function(struct tree *root, int num). I see what you're getting at though, I appreciate the solution. – alldavidsluck Jan 27 '14 at 21:49
  • @alldavidsluck even better, just rewrite call to insert like that : root = insert(root, num); – Dabo Jan 27 '14 at 21:51
  • Yes, @BLUEPIXY had the same solution as well. Just to make sure I'm understanding the reasons as well, it was because I was allocating in main and then passing it by reference, instead of passing and then allocating? – alldavidsluck Jan 27 '14 at 21:54
  • You were allocating memory for root node in main, and passing the pointer by value. The value of the pointer was address of just allocated piece of memory, with default value of field `data` which is `0`. Because value of the pointer was not `NULL` first if never was true, so your root node always stayed with default value. – Dabo Jan 27 '14 at 22:05