2016-11-01 112 views
0

这里我试图实现一个二叉搜索树。我在全局上下文中声明了根节点。我遵循同样的想法,我如何实现链表。但是这种方法看起来并不像工作。我找不出什么是错在这code.Can谁能帮我算出这个为什么没有元素被插入到我的BST中

#include<stdio.h> 
struct node { 

    int data; 
    struct node *left; 
    struct node *right; 
}; 
void insert(int value); 
void push(struct node *temp,struct node *newNode); 


struct node *root; 
int main(){ 
    root= NULL; 
    int option,value; 
    for(;;){ 
     printf("Please select an option from below : \n"); 
     printf("1 for insert\n"); 
     printf("2 for search\n"); 
     printf("please enter your option : "); 
     scanf("%d",&option); 
     printf("\n"); 
     switch(option){ 
      case 1: 
       printf("you choose to insert\n"); 
       printf("input your value :"); 
       scanf("%d",&value); 
       insert(value); 
       printf("\n"); 
       break; 
      case 2: 
       printf("You choose to search\n"); 
       printf("enter your value : "); 
       scanf("%d",&value); 
       search(root,value); 
       printf("\n"); 
      default: 
       break; 

     } 
    } 
} 

void insert(int value){ 
    struct node *newNode = (struct node *)malloc(sizeof(struct node)); 

    newNode->data = value; 
    newNode->left = NULL; 
    newNode->right = NULL; 


    push(root,newNode); 

} 
void push(struct node *root_node,struct node *newNode){ 

    if(root_node==NULL){ 
     root_node = newNode; 
     printf("inserted\n\n\n"); 
    }else{ 
     if(root_node->data > newNode->data){ 
       push(root_node->left,newNode); 
       printf("left\n"); 
     }else{ 
      push(root_node->right,newNode); 
      printf("right\n"); 
     } 

    } 

} 
+2

'push()','root_node = newNode;'没有任何用处,因为它不影响调用代码。这一个很多愚蠢。也许[这一个](http://stackoverflow.com/questions/20172603/why-do-we-need-to-return-the-head-pointer-in-a-bst-after-inserting-node)? – chux

+0

可以请你解释一下..我还是很困惑! –

+0

搜索并阅读*模拟C *中的引用传递。 –

回答

3

push(),root_node是局部变量

void push(struct node *root_node,struct node *newNode){ 

当你这样做:

root_node = newNode; 

你只更新本地变量 “root_node”,而不是全球:

struct node *root; 

你推()应该是这样的:

void push(struct node **root_node,struct node *newNode){ 
    if(*root_node==NULL){ 
     *root_node = newNode; 
     printf("inserted\n\n\n"); 
    }else{ 
... 

,并呼吁:

push(&root, newNode); 

通过这种方式,你传递根的地址,并在里面检查是否指向那个地址是NULL。如果它为空,则将newNode的地址分配给指针dereferenced

更多的解释:

struct node *root是一个指针:一个变量谁的类型是“指针/地址”。并指向数据存储区块,我们称之为“A”。

struct node *root_node是一个指针,因为局部变量,它是一个COPY,它指向在数据存储器中,并且在你的情况的块(因为传递“根”)指向“A”。

当您修改root_node时,您的副本不会修改root。你在做什么只能用来修改“A”。

你必须通过地址根,所以实际上你可以修改root的价值,这是一个指向“A”。这样,你有** root_node这是指向root,实际root,指向“A”,你可以指向其他地方(如你所愿)指针。

我上传图片,说明为什么你的解决方案是错误的:

enter image description here

正如你所看到的,root从未更新。因为指针是一个变量,其值是一个地址,您可以用*variable来解除引用地址)。(可以将“复制指针”读为“复制变量”。

+0

在你的推送函数中if(* root_node == NULL)这里... * root_node表示&root的地址....不是吗?所以地址不能为空..所以我应该如何插入第一个节点? –

+0

不,'root_node'是'&root'(root的地址),然后'* root_node'是'root'。你读过链接https://en.wikipedia.org/wiki/Dereference_operator了吗?以图形方式提供解除引用:http://images.slideplayer.com/19/5772771/slides/slide_38.jpg。让我们试试这个来理解它:在我的push()里面有什么是你的变量,堆和栈以及它们指向哪里,等等。:) –

+0

我忘了发表评论。在我的push()函数中,你可以用'(*(* root_node))。data'来访问节点的数据:)。记住'(* variable).field'可以写成'variable-> field'的句法小技巧,所以你可以把'(*(* root_node))。data'写成'(* root_node) - > data' –

0

以下行是不是更新全局变量root

push(root,newNode); 

} 
void push(struct node *root_node,struct node *newNode){ 

    if(root_node==NULL){ 
     root_node = newNode; 
     printf("inserted\n\n\n"); 

既然你想root是全球性的,一种选择是,这样使用全局root通过以下方式来改变这种状况。

push(newNode); 

} 
void push(struct node *newNode){ 

    if(root == NULL){ 
     root = newNode; 
     printf("inserted\n\n\n"); 

等等。 (注意:这不是一个完整的解决方案。)

+0

struct node * root_node是一个指向根节点的指针。为什么它不应该更新它? –

+0

在你的第二个例子中,我如何处理递归调用,如果我省略root_node参数? –

+0

因为'root_node'是一个局部变量,'root_node'的更新不会反映在'root'上。 – Arun

相关问题