2017-04-18 32 views
0

到目前为止,程序足够简单:由包含整数值的节点和指向节点左右分支的指针组成的二叉树。尝试在二叉树的根目录处打印值时发生崩溃

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

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

void insert(Node *root, int val); 

int main(void){ 
    Node *root = NULL; 

    insert(root, 5); 
    insert(root, 3); 

    printf("%d\n", root->val); 


    return 0; 
} 

void insert(Node *root, int val){ 
    if(root == NULL){ // Create tree if root is empty 
     root = malloc(sizeof(struct node)); 
     root->val = val; 
     root->left = NULL; 
     root->right = NULL; 
    } else if(val < root->val){ // branch to left of tree if new value is less than root value 
     if(root->left == NULL){ 
      root->left = malloc(sizeof(struct node)); 
     } 

     root->left->val = val; 
    } else if(val > root->val){ // branch to right of tree if new value is greater than root value 
     if(root->right == NULL){ 
      root->right = malloc(sizeof(struct node)); 
     } 

     root->right->val = val; 
    } 
} 

无论出于何种原因,插入效果都不错。我可以输入5和3(任意)的罚款。但是我不能打印出应该在root-> val中的值'5'?该程序完全崩溃。我忽略了什么?

+2

尝试在第一个insert()后打印'root'的指针值 - 这不是你想象的那样.... – John3136

+0

我似乎有愚蠢。 – Sato

+0

你的一个愚蠢的方式是没有做研究。 SO上大约一半的链表/树帖子都有这个'只更新本地变量'的问题。 – ThingyWotsit

回答

1

的问题是在insert签名:

void insert(Node *root, int val); 

它不可能采取NULLroot参数,因为它没有办法沟通回来,恰好它的函数内部的变化。 insert中的root的任何修改仍然局限于insert,因为指针是按值传递的,即复制了

你有一个良好的签名两种通用的选择:

  • 制作insert返回新root,即Node *c如果你使用这种方法,调用者将需要拨打电话如下:root = insert(root, 5);
  • 通过Node**而不是Node*,即void insert(Node **root, int val);如果您使用此方法,呼叫者将需要拨打电话如下:insert(&root, 5)。当然,insert的实现也需要改变,因为额外的间接级别需要额外的解引用。
+0

谢谢。我需要刷新它的范围和内存。 – Sato

+0

我认为你需要刷新[传值](http://stackoverflow.com/questions/373419/whats-the-difference-between-passing-by-reference-vs-passing-by-value); *范围和内存*似乎是正交的。 – Sebivor