2015-04-05 8 views
0
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

typedef struct node_{ 
    int val; 
    struct node_ *left; 
    struct node_ *right; 
}node; 

node* insert(node* root,int val); 
void inorder(node* root); 
int main(void) 
{ 
    int i; 
    int item; 
    node* root = NULL; 

    srand(time(NULL)); 

    for(i = 0; i < 10; i++) 
    { 
     item = rand()%15; 
     insert(root,item); 
    } 

    inorder(root); 

    return 0;  
} 

node* insert(node* root,int val) 
{ 
    if(root == NULL) 
    { 
     root = malloc(sizeof(node)); 
     if(root!= NULL) 
     { 
      (root)->val = val; 
      (root)->left = NULL; 
      (root)->right = NULL; 
     } 
     else 
      printf("%d not inserted. No memory available.\n",val); 
    } 
    else 
    { 
     if(val < (root)->val) 
     { 
      insert((root->left),val); 
     } 

     if(val>root->val) 
     { 
      insert(((root)->right),val); 
     } 
    } 
} 

void inorder(node* root) 
{ 
    printf("%p",root); 
    if(root != NULL) 
    { 
     inorder(root->left); 
     printf("%3d",root->val); 
     inorder(root->right); 
    } 
} 

Я пытаюсь создать двоичное дерево и распечатать значения в порядке. Однако, когда я запускаю этот код, printf адреса печатает нуль, что явно означает, что мое дерево пуст, поэтому printf и рекурсия ниже не выполняются. Я не могу понять, где я поступил неправильно, любые предложения или ответы были бы оценены, потому что я не могу понять, почему корень был бы нулевым после вызова всех этих вставок в главном.Использование двоичного дерева

+0

Неудачное выделение выделяется? (root) не имеет смысла и может вызвать проблемы с изменением только root –

ответ

0

Вы передаете root в качестве параметра insert() (в котором говорится, что он что-то вернет, но не делает). Внутри insert вы получите malloc ваш узел и назначьте его локальной переменной root. Ничто из того, что вы когда-либо делали, делает его вне функции insert.

Попробуйте что-то вернуть с insert или с помощью глобальной сети root.

Как @JoshuaByer намекает на комментарии ниже, другой подход заключается в том, чтобы сделать ваш метод insert «пройденным по ссылке», чтобы он мог эффективно модифицировать то, что ему было передано.

void insert(node** rootp,int val) 
{ 
    if(*rootp == NULL) 
    { 
     *rootp = malloc(sizeof(node)); 
    } 
    /* and so on */ 

Если вы не понимаете, что это говорит, Google «Передавать по ссылке в C», и я уверен, вы получите полезную информацию.

+0

Root не является локальной переменной, в которую он передается как указатель на функцию –

+0

@JoshuaByer Хорошо, это параметр. Как семантика отличается от локальной переменной? Это не волшебным образом становится проходом по ссылке – John3136

+0

Очень хорошая проблема, которую он хочет передать по ссылке .. отрегулируйте ответ соответственно –

0

В main() после объявления и инициализации корня (node* root = NULL;) вы никогда не назначаете его. Чтобы исправить это, вы должны, вероятно, изменить lin insert(root,item); на root = insert(root,item);.

Также обратите внимание, что хотя insert определяется как возвращаемый node *, он не возвращает никакого значения.

+0

во вставке, если он равен нулю –

+0

Это назначение бессмысленно и действует только в области 'insert()'. Чтобы изменить значение указателя, вы должны передать его адрес (т.е. '& root' типа' node ** '), а затем изменить его, обратившись к' * ppRoot' –