2016-11-01 68 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

相關問題