简体   繁体   中英

How to insert numbers into a binary search tree in C?

I am trying to insert a list of numbers into a binary search tree by calling the TREEinsert function frim the main function however whenever my program runs it does not print any number inserted into the binary search tree. I have gone over both my TREEinsert function and Displayinorder function but cannot seem to find any issues with the functionality of either function. I have a basic understanding of binary search trees and have looked at many examples trying to get an insight as to how BST's work. Any guidance will be greatly helpful.

struct node
 {
     int info;
     struct node *left;
     struct node *right;
 };



void TREEclear(struct node* t)
{
     t = NULL;
}

void TREEinsert(struct node*  t, int x)
{

    //insert in BST
    if(t == NULL)
    {
        t = (struct node*)malloc(sizeof(struct node));
        t->info = x;
        t->left = NULL;
        t->right = NULL;
    }
    else
    {
        if (x < t->info)
        TREEinsert(t->left, x);
        if (x > t->info)
            TREEinsert(t->right, x);
    }
}

void Displayinorder(struct node* t)
{
    //in order: (LC)(P)(RC)
    if (t != NULL)
    {
        Displayinorder(t->left); //LC
        printf("%d\t", t->info); //P
        Displayinorder(t->right); //RC
    }
}

struct node *root;

int main()
{
    TREEclear(root);

    TREEinsert(root, 5);
    TREEinsert(root, 8);
    TREEinsert(root, 2);
    TREEinsert(root, 6);

    Displayinorder(root);

    printf("\n\n");
    system("PAUSE");
    return 0;
 }

The node pointer t is a local variable in TREEinsert . Any changes you make to it are not reflected in the calling function.

You should pass the address of the root pointer as struct node *p from the calling function. When you recurse, pass the adress of the left or right pointer of te current node respectively.

Here's how:

#include <stdlib.h>
#include <stdio.h>

struct node {
    int info;
    struct node *left;
    struct node *right;
};


void TREEclear(struct node *t)
{
    t = NULL;
}

void TREEinsert(struct node **t, int x)
{
    if (*t == NULL) {
        *t = malloc(sizeof(**t));
        // TODO: check allocation success

        (*t)->info = x;
        (*t)->left = NULL;
        (*t)->right = NULL;
    } else {
        if (x < (*t)->info) TREEinsert(&(*t)->left, x);
        if (x > (*t)->info) TREEinsert(&(*t)->right, x);
    }
}

void Displayinorder(struct node *t)
{
    if (t != NULL) {
        Displayinorder(t->left);
        printf("%d\n", t->info);
        Displayinorder(t->right);
    }

}

int main()
{
    struct node *root = NULL;

    TREEinsert(&root, 5);
    TREEinsert(&root, 8);
    TREEinsert(&root, 2);
    TREEinsert(&root, 6);

    Displayinorder(root);

    // TODO: need to free the tree nodes

    return 0;
}

Note that you pass &root to the insertion function, which may have to modify it, but just root to the display functon, which only has to inspect it.

I've gotten rid of your TREEclear function. First, it has the same problems as your original TREEinsert : it modifies a local variable and doesn't change anything in main . Second, this function should free all nodes, not just set the root to NULL . (That said, you should write this function, so that you can deallocate the tree after use.)

The t in your TREEinsert function is a local variable so from there you have two options: either you return it and have the code like below, or your parameter t should be a struct node**
So first option is:

 struct node* TREEinsert(struct node*  t, int x)
 {

  //insert in BST
  if(t == NULL)
  {

    t = (struct node*)malloc(sizeof(struct node));
    t->info = x;
    t->left = NULL;
    t->right = NULL;
    return t ;
  }
 else
  {
    if (x < t->info)
        return(TREEinsert(t->left, x));
    if (x > t->info)
       return(TREEinsert(t->right, x));
  }


}

Second option is:

void TREEinsert(struct node **t, int x)
{
    if (*t == NULL) {
        *t = malloc(sizeof(**t));
        (*t)->info = x;
        (*t)->left = NULL;
        (*t)->right = NULL;
    } else {
        if (x < (*t)->info) 
            TREEinsert(&(*t)->left, x);
        if (x > (*t)->info) 
            TREEinsert(&(*t)->right, x);
    }
}

Side-note: you may want to check whether your malloc succeeded or not.

First of all function TREEclear does not set to zero the original head of three. It deals with a copy of the head. The original head is not changed.

Also the name of the function is confusing. It is better to name it for example like TREEinit .

It can look the following way

void TREEinit( struct node * *t)
{
    *t = NULL;
}

Recursive function TREEinsert can look like

void TREEinsert( struct node * *t, int x )
{
    if ( *t == NULL )
    {
        *t = ( struct node* )malloc( sizeof( struct node ) );
        ( *t )->info = x;
        ( *t )->left = NULL;
        ( *t )->right = NULL;
    }
    else if (  x < ( *t )->info )
    {       
        TREEinsert( &( *t )->left, x );
    }
    else if ( x > ( *t )->info )
    {
        TREEinsert( &( *t )->right, x );
    }
}

and it should be called like

TREEinsert( &root, 5 );

Take into account that you need to write also a function that will free all allocated memory for the tree.

There is two way to fixed it
1. change the return type of Insert function 


Struct node * TREEinsert(){
              //your code

            return the local variable( t)
           }

2. If you don't want to change the return type of function then change the argument you are passing to Insert function
            TREEinsert(&root, intVariable);
    and in  TREEinsert(Struct node **,int);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM