简体   繁体   中英

Binary Search Tree Insert Function In C

For future viewers of this question who might need help in this type of problem: I fixed it by combining the 2 functions (InsertNode() and InTree()) I'm not sure if this is bad practice and I'll get back to you guys with if it actually really does solve the problem or if it just masks it, but it seems to be working...

I've looked through various answers on this website (as well as others) and from those I've gotten solutions which didn't help (tried and didn't work or just didn't differ from my program). The insert function (I've isolated it and think this is the problematic code) has some bug somewhere that causes my program to crash.

NP InTree(NP Node,NP Root)
{
    if (Root == NULL)
    {
        Root=Node;
        return Root;
    }
    else
    {
        if (Node->Input < Root->Input)
        {
            return InTree(Node,Root->Left);
        }
        else if (Node->Input > Root->Input)
        {
            return InTree(Node,Root->Right);
        }
        else
        {
            puts("Duplicate");
            return NULL;
        }
    }
}

void InsertNode(int I, TP Tree)
{

    NP Node;
    Node=(NP)malloc(sizeof(struct AVLNode));
    InitializeNode(Node);
    Node->Input=I;
    Node->Height=0;
    Node->Left=NULL;
    Node->Right=NULL;
    InTree(Node,Tree->Root);
    Tree->Size++;
}

NP is a Node Pointer, TP is a Tree Pointer

The Node variable is the initialized node sent through InsertNode()

void InitializeTree(TP Tree)
{

    Tree->Root=NULL;
    Tree->Size=0;
}

void InitializeNode(NP Node)
{

    Node->Input=0;
    Node->Height=0;
}

The above are my Initialize functions just in case you need to see them.

The memory for the Tree is allocated in the main class before any of the functions are called.

The main problem from what I saw through testing is that once Root is made equal to Node it remains null.

Any ideas how I can get past the problem?

void InsertNode(int I, TP Tree) allocates mem for a new node, but when you call NP InTree(NP Node,NP Root) you only modify the local pointer address. You need to either use a pointer to a pointer (ie NP InTree(NP Node, NP *ppRoot) ) or the following example:

if (Node->Input < Root->Input) {
    if(Root->Left == NULL) {
        Root->Left = Node;
    } else {
        return InTree(Node,Root->Left);
    }
} else if (Node->Input > Root->Input) {
    if(Root->Right== NULL) {
        Root->Right= Node;
    } else {
        return InTree(Node,Root->Right);
    }
} else {
    puts("Duplicate");
    return NULL;
}

Ps. I notice you allocate struct AVLNode...is NP a typedef of AVLNode ( typedef struct AVLNode* NP )? I don't know what your structures are so I can't say. Technically AVLs are different from B-trees in that they are self balancing... http://en.wikipedia.org/wiki/AVL_tree

In the InTree function, where the Root is made equal to Node , it only changes the memory locally.

Instead, you may need to use a pointer to a pointer to achieve what you're trying.

I'd do it something like this. Your insert function doesn't differentiate between the special case (an empty tree) and the general case (a non-empty tree).

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

typedef struct NODE
{
  struct NODE *left  ;
  struct NODE *right ;
  int          value ;
  int          depth ;
} NODE ;

typedef struct TREE
{
  NODE *root  ;
  int   count ;
} TREE ;

NODE *node_create( int value )
{
  NODE *instance = (NODE*) calloc( 1 , sizeof(NODE) ) ;
  instance->value = value ;
  return instance ;
}

TREE *tree_create()
{
  TREE *instance = (TREE*) calloc( 1 , sizeof(TREE) ) ;
  return instance ;
}

NODE *tree_find_and_insert( NODE *parent , int value )
{
  NODE *child = NULL ;

  if ( value < parent->value )
  {
    if ( parent->left == NULL )
    {
      child = node_create(value) ;
      child->depth = ++ parent->depth ;
      parent->left = child ;
      return child ;
    }
    else
    {
      return tree_find_and_insert(parent->left , value ) ;
    }
  }
  else if ( value > parent->value )
  {
    if ( parent->right == NULL )
    {
      child = node_create(value) ;
      child->depth = ++ parent->depth ;
      parent->right = child ;
      return child ;
    }
    else
    {
      return tree_find_and_insert( parent->right , value ) ;
    }
  }
  else /* ( value == parent->value ) */
  {
    // NO-OP by design: dupes fall out and NULL is returned
  }

  return child ;
}

NODE *tree_insert( TREE *tree , int value )
{
  NODE *inserted = NULL ;
  if ( tree->root == NULL )
  {
    tree->root  = node_create( value ) ;
    tree->count = 1 ;
    inserted = tree->root ;
  }
  else
  {
    inserted = tree_find_and_insert( tree->root , value ) ;
  }
  return inserted ;
}

int main ( int argc , char *argv[] )
{
  TREE *my_tree = tree_create() ;
  int i ;

  for ( i = 1 ; i < argc ; ++i )
  {
    char *arg = argv[i] ;
    int   n   = atoi(arg) ;

    tree_insert( my_tree , n ) ;

  }

  return 0 ;
}

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