简体   繁体   中英

Binary Search Tree insertion not working

I've been playing about with this Binary search tree for a while but I can't seem to insert or change any of the tree properties.

My binary tree is defined as:

struct tree{
    Node * root;
    int size;
};
struct node{
    int value;
    Node * left;
    Node * right;
};

Therefore my binary tree is composed of nodes. Now the bit that doesn't work:

void add(int value, Tree *t){
    //1. if root is null create root
    if(t->root == NULL){
        t->root = nodeCreate(value);
        t->size ++;
        return;
    }
    Node * cursor = t->root;

    while(cursor != NULL){
        if(value == cursor->value){
            printf("value already present in BST\n");
            return;
        }
        if(value < cursor->value){
            cursor = cursor->left;
        }
        if(value > cursor->value){
            cursor = cursor->right;
        }
    }
    //value not found in BST so create a new node.
    cursor = nodeCreate(value);
    t->size = t->size + 1;
}

Can someone tell me where I'm going wrong? I expected calls to add() would increase the size member as well as creating new nodes but I can't seem to get it.

I believe the changes below will fix your problem.

void add(int value, Tree *t){
    if(t->root == NULL){
        t->root = nodeCreate(value);
        t->size ++;
        return;
    }
    Node * cursor = t->root;
    Node * last = null;
    while(cursor != NULL){
        last = cursor;
        if(value == cursor->value){
            printf("value already present in BST\n");
            return;
        }
        if(value < cursor->value){
            cursor = cursor->left;
        }
        if(value > cursor->value){
            cursor = cursor->right;
        }
    }
    //value not found in BST so create a new node.
    cursor = nodeCreate(value);
    if (value > cursor->value)
    {
        last->right = cursor;
    }
    else
    {
        last->left = cursor;
    }
    t->size = t->size + 1;
}

You're have both a design flaw and an outright-bug in your loop.

The design flaw: You're allocating a new node, but assigning to cursor doesn't mean you're assigning to the parent node left or right child pointer that got you there in the first place. You need a reference to the actual pointer you're going to populate. One way to do this is with a pointer-to-pointer, and as a bonus, this eliminates the is-my-root-null check at the beginning.

The outright bug: Your left-side movement clause (ie chasing a left-side pointer) will potentially change cursor to NULL. but the logic for chasing the right side is not excluded with an else if condition. If your search followed a left-side to null it would fault chasing the right side of a null pointer. This was obviously a problem.

void add(int value, Tree *t)
{
    Node **pp = &(t->root);
    while (*pp)
    {
        if(value == (*pp)->value) {
            printf("value already present in BST\n");
            return;
        }
        if(value < (*pp)->value)
            pp = &(*pp)->left;

        else if(value > (*pp)->value)
            pp = &(*pp)->right;
    }
    *pp = nodeCreate(value);
    t->size++;
}

I should also note that you can skip the equality check by assuming a strict-weak order. Ie the following rule can be considered valid:

if (!(a < b) && !(b < a)) then a == b is true.

That makes your insertion simpler as well.

void add(int value, Tree *t)
{
    Node **pp = &(t->root);
    while (*pp)
    {
        if (value < (*pp)->value)
            pp = &(*pp)->left;

        else if ((*pp)->value < value)
            pp = &(*pp)->right;

        else { // must be equal.
            printf("value already present in BST\n");
            return;
        }
    }
    *pp = nodeCreate(value);
    t->size++;
}

You're not assigning any of your existing nodes to point to the new node. You walk through the tree, create a new node when you get to the end, but you don't set any existing nodes to point to the new node.

You might want to change your structure to something like:

if ( value < cusor->value )
{
  if ( cursor->left )
  {
    cursor = cursor->left;
  }
  else
  {
    cursor->left = newNode(value);
    break;
  }
}

with similar logic for the right-hand cursor.

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